fast

package
v0.0.0-...-48c8420 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 6, 2017 License: LGPL-3.0 Imports: 21 Imported by: 0

README

gomacro - A Go interpreter with Lisp-like macros

The package fast contains a faster reimplementation of gomacro interpreter.

To learn about gomacro, download, compile and use it, please refer to the original implementation README.md

If you want to help with the reimplementation, or you are simply curious, read on :)

Current Status

STABLE.

The fast interpreter supports:

  • multiline input - shared with the classic interpreter
  • line comments starting with #! in addition to // - shared with the classic interpreter
  • basic types: booleans, integers, floats, complex numbers, strings (and iota)
  • the empty interface, i.e. interface{} - other interfaces not implemented yet
  • constant, variable and type declarations (including untyped constants)
  • Go 1.9 type aliases (experimental)
  • unary and binary operators
  • assignment, i.e. operators := = += -= *= /= %= &= |= ^= <<= >>= &^=
  • composite types: arrays, channels, maps, pointers, slices, strings, structs (including composite literals)
  • accessing struct fields, including embedded fields
  • slicing
  • type assertions and type conversions
  • interface declarations (only declarations. interfaces cannot be implemented or used yet)
  • importing and using interfaces declared (and implemented) by compiled code
  • function declarations and calls, including variadic functions
  • method declarations and calls, including wrapper methods for embedded fields
  • closures
  • Type.Method i.e. converting methods to functions (examples: time.Duration.Hours, fmt.Stringer.String)
  • seamless invocation of compiled functions from interpreter, and vice-versa
  • if, for, range, select, switch, type switch, break, continue, fallthrough, return (unimplemented: goto)
  • all builtins: append, cap, close, complex, defer, delete, imag, len, make, new, panic, print, println, real, recover
  • go i.e. goroutines
  • imports
    • Go standard packages "just work"
    • importing other packages requires the "plugin" package (available only on Linux with Go 1.8+)
  • ~quote, ~quasiquote, ~unquote, ~unquote_splice
  • macro declarations, for example macro foo(a, b, c interface{}) interface{} { return b }
  • macro calls, for example foo; x; y; z

Missing features - you are welcome to contribute:

  • goto
  • interfaces. They can be declared, but nothing more: there is no way to implement them or call their methods (interfaces declared in compiled code can be used, but not yet implemented by interpreted code)
  • conversion from/to interpreted interfaces

Current limitations:

  • named types declared by interpreted code are approximated. Inside the interpreter they look and behave correctly, but if you pass them to compiled code, the type is actually unnamed.

    For example, if interpreted code declares type Pair struct { A, B int }, then passes a Pair to compiled code, it will be received as struct { A, B int }

    The reason for such limitation is simple: the function reflect.NamedOf() does not exist, so the interpreter uses reflect.StructOf() to define new types, which can only create unnamed types.

  • recursive types declared by interpreted code are approximated. Inside the interpreter they look and behave correctly, but if you pass them to compiled code, the type is unnamed (as above) and self-references are actually interface{}.

    For example, if interpreted code declares type List struct { First int; Rest *List } then passes a List to compiled code, it will be received as struct { First int; Rest *interface{} }

    The reason is the same as above: the interpreter uses reflect.StructOf() to define new types, which cannot create recursive types.

    Interestingly, this means the interpreter also accepts the following declaration, which is rejected by Go compiler: type List2 struct { First int; Rest List2 } Note that Rest is a List2 not a pointer to List2

  • interfaces declared by interpreted code are emulated. Inside the interpreter they look and behave correctly, but if you pass them to compiled code, the type is actually a pointer to a struct containing a header and a lot of functions.

    The reason is: the function reflect.InterfaceOf() does not exist, so the interpreter has to emulate interfaces with reflect.StructOf() and a lot of bookkeeping

  • operators << and >> on untyped constants do not follow the exact type deduction rules. The implemented behavior is:

    • an untyped constant shifted by a non-constant expression always returns an int
    • an untyped floating point constant shifted by a constant expression returns an untyped integer constant. the interpreter signals an error during the precompile phase if the left operand has a non-zero fractional or imaginary part, or it overflows both int64 and uint64. See Go Language Specification for the correct behavior
  • recover() does not support mixing interpreted and compiled code: if an interpreted function invokes as defer a compiled function, or a compiled function invokes as defer an interpreted function, then, inside that defer, recover() will not work: it will return nil and will not stop panics.

    recover() works normally if the function and its defer are either both interpreted or both compiled.

Misc TODO notes:

  • when importing a package, reuse compiled .so if exists already
  • gomacro FILE: execute main() if (re)defined and package == "main"
  • try to run Go compiler tests

Documentation

Index

Constants

View Source
const (
	ConstBind = BindClass(iota)
	FuncBind
	VarBind
	IntBind
)
View Source
const (
	NoIndex             = int(0)                    // index of constants, functions and variables named "_"
	ConstBindDescriptor = BindDescriptor(ConstBind) // bind descriptor for all constants
)
View Source
const (
	// conventional values
	AnyDepth  = -1
	FileDepth = -2
	TopDepth  = -3
)
View Source
const (
	PoolCapacity = 32
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Assign

type Assign struct {
	// contains filtered or unexported fields
}

type Bind

type Bind struct {
	Lit
	Desc BindDescriptor
	Name string
}

Bind represents a constant, variable, function or builtin in the "compiler"

func (*Bind) AsSymbol

func (bind *Bind) AsSymbol(upn int) *Symbol

func (*Bind) AsVar

func (bind *Bind) AsVar(upn int, opt PlaceOption) *Var

func (*Bind) Const

func (bind *Bind) Const() bool

func (*Bind) ConstValue

func (bind *Bind) ConstValue() r.Value

func (*Bind) String

func (bind *Bind) String() string

type BindClass

type BindClass int

func (BindClass) String

func (class BindClass) String() string

type BindDescriptor

type BindDescriptor BindClass

the zero value of BindDescriptor is a valid descriptor for all constants

func MakeBindDescriptor

func MakeBindDescriptor(class BindClass, index int) BindDescriptor

func (BindDescriptor) Class

func (desc BindDescriptor) Class() BindClass

IntBind returns true if BindIndex refers to a slot in Env.IntBinds (the default is a slot in Env.Binds)

func (BindDescriptor) Index

func (desc BindDescriptor) Index() int

Index returns the slice index to use in Env.Binds or Env.IntBinds to access a variable or function. returns NoIndex for variables and functions named "_"

func (BindDescriptor) Settable

func (desc BindDescriptor) Settable() bool

func (BindDescriptor) String

func (desc BindDescriptor) String() string

type Builtin

type Builtin struct {
	// interpreted code should not access "compile": not exported.
	// compile usually needs to modify Symbol: pass it by value.
	Compile func(c *Comp, sym Symbol, node *ast.CallExpr) *Call
	ArgMin  uint16
	ArgMax  uint16
}

Builtin represents a builtin function in the fast interpreter

type Call

type Call struct {
	Fun      *Expr
	Args     []*Expr
	OutTypes []xr.Type
	Builtin  bool // if true, call is a builtin function
	Const    bool // if true, call has no side effects and always returns the same result => it can be invoked at compile time
	Ellipsis bool // if true, must use reflect.Value.CallSlice or equivalent to invoke the function
}

func (*Call) MakeArgfunsX1

func (call *Call) MakeArgfunsX1() []func(*Env) r.Value

type Code

type Code struct {
	List       []Stmt
	DebugPos   []token.Pos // for debugging interpreted code: position of each statement
	WithDefers bool        // true if code contains some defers
}

func (*Code) Append

func (code *Code) Append(stmt Stmt, pos token.Pos)

func (*Code) AsExpr

func (code *Code) AsExpr() *Expr

func (*Code) Clear

func (code *Code) Clear()

func (*Code) Exec

func (code *Code) Exec() func(*Env)

Exec returns a func(*Env) that will execute the compiled code

func (*Code) Len

func (code *Code) Len() int

type Comp

type Comp struct {
	Binds      map[string]*Bind
	BindNum    int // len(Binds) == BindNum + IntBindNum + # of constants
	IntBindNum int
	// UpCost is the number of *Env.Outer hops to perform at runtime to reach the *Env corresponding to *Comp.Outer
	// usually equals one. will be zero if this *Comp defines no local variables/functions.
	UpCost         int
	Depth          int
	Types          map[string]xr.Type
	Code           Code      // "compiled" code
	Loop           *LoopInfo // != nil when compiling a for or switch
	Func           *FuncInfo // != nil when compiling a function
	Outer          *Comp
	Name           string // set by "package" directive
	Path           string
	CompileOptions CompileOptions
	*CompThreadGlobals
}

Comp is a tree-of-closures builder: it transforms ast.Nodes into closures for faster execution. Consider it a poor man's compiler (hence the name)

func NewComp

func NewComp(outer *Comp, code *Code) *Comp

func (*Comp) Add

func (c *Comp) Add(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) AddBind

func (c *Comp) AddBind(name string, class BindClass, t xr.Type) *Bind

AddBind reserves space for a subsequent constant, function or variable declaration

func (*Comp) AddFuncBind

func (c *Comp) AddFuncBind(name string, t xr.Type) *Bind

AddFuncBind reserves space for a subsequent function declaration

func (*Comp) AddressOf

func (c *Comp) AddressOf(node *ast.UnaryExpr) *Expr

func (*Comp) AddressOfVar

func (c *Comp) AddressOfVar(name string) *Expr

func (*Comp) And

func (c *Comp) And(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Andnot

func (c *Comp) Andnot(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Append

func (c *Comp) Append(stmt Stmt, pos token.Pos)

func (*Comp) Assign

func (c *Comp) Assign(node *ast.AssignStmt)

Assign compiles an *ast.AssignStmt into an assignment to one or more place

func (*Comp) BasicLit

func (c *Comp) BasicLit(node *ast.BasicLit) *Expr

func (*Comp) BinaryExpr

func (c *Comp) BinaryExpr(node *ast.BinaryExpr) *Expr

func (*Comp) BinaryExpr1

func (c *Comp) BinaryExpr1(node *ast.BinaryExpr, x *Expr, y *Expr) *Expr

func (*Comp) BinaryExprUntyped

func (c *Comp) BinaryExprUntyped(node *ast.BinaryExpr, x UntypedLit, y UntypedLit) *Expr

func (*Comp) BindUntyped

func (c *Comp) BindUntyped(value UntypedLit) *Bind

func (*Comp) Block

func (c *Comp) Block(block *ast.BlockStmt)

Block compiles a block statement, i.e. { ... }

func (*Comp) Branch

func (c *Comp) Branch(node *ast.BranchStmt)

Branch compiles a break, continue, fallthrough or goto statement

func (*Comp) Break

func (c *Comp) Break(node *ast.BranchStmt)

Break compiles a "break" statement

func (*Comp) CallExpr

func (c *Comp) CallExpr(node *ast.CallExpr) *Expr

CallExpr compiles a function call or a type conversion

func (*Comp) Compile

func (c *Comp) Compile(in Ast) *Expr

func (*Comp) CompileNode

func (c *Comp) CompileNode(node ast.Node) *Expr

func (*Comp) CompositeLit

func (c *Comp) CompositeLit(node *ast.CompositeLit) *Expr

func (*Comp) Continue

func (c *Comp) Continue(node *ast.BranchStmt)

Continue compiles a "continue" statement

func (*Comp) Convert

func (c *Comp) Convert(node ast.Expr, t xr.Type) *Expr

Convert compiles a type conversion expression

func (*Comp) Converter

func (c *Comp) Converter(tin, tout xr.Type) func(val r.Value, rtout r.Type) r.Value

Converter returns a function that converts reflect.Value from tin to tout also supports conversion from interpreted types to interfaces

func (*Comp) Decl

func (c *Comp) Decl(node ast.Decl)

Decl compiles a constant, variable, function or type declaration - or an import

func (*Comp) DeclBindRuntimeValue

func (c *Comp) DeclBindRuntimeValue(bind *Bind) func(*Env, r.Value)

DeclBindRuntimeValue compiles a variable, function or constant declaration with a reflect.Value passed at runtime

func (*Comp) DeclBuiltin0

func (c *Comp) DeclBuiltin0(name string, builtin Builtin) *Bind

DeclBuiltin0 compiles a builtin function declaration. For caller's convenience, returns allocated Bind

func (*Comp) DeclConst0

func (c *Comp) DeclConst0(name string, t xr.Type, value I)

DeclConst0 compiles a constant declaration

func (*Comp) DeclConsts

func (c *Comp) DeclConsts(node ast.Spec, defaultType ast.Expr, defaultExprs []ast.Expr)

DeclConsts compiles a set of constant declarations

func (*Comp) DeclConsts0

func (c *Comp) DeclConsts0(names []string, t xr.Type, inits []*Expr)

func (*Comp) DeclEnvFunc0

func (c *Comp) DeclEnvFunc0(name string, envfun Function) *Bind

DeclEnvFunc0 compiles a function declaration that accesses interpreter's Env. For caller's convenience, returns allocated Bind

func (*Comp) DeclFunc0

func (c *Comp) DeclFunc0(name string, fun I) *Bind

DeclFunc0 compiles a function declaration. For caller's convenience, returns allocated Bind

func (*Comp) DeclMultiVar0

func (c *Comp) DeclMultiVar0(names []string, t xr.Type, init *Expr)

DeclMultiVar0 compiles multiple variable declarations from a single multi-valued expression

func (*Comp) DeclNamedType

func (c *Comp) DeclNamedType(name string) xr.Type

DeclNamedType executes a named type forward declaration. Returns nil if name == "_" Otherwise it must be followed by Comp.SetUnderlyingType()

func (*Comp) DeclType

func (c *Comp) DeclType(node ast.Spec)

DeclType compiles a type declaration.

func (*Comp) DeclType0

func (c *Comp) DeclType0(t xr.Type) xr.Type

DeclType0 declares a type in Go, types are computed only at compile time - no need for a runtime *Env

func (*Comp) DeclTypeAlias

func (c *Comp) DeclTypeAlias(name string, t xr.Type) xr.Type

DeclTypeAlias compiles a typealias declaration, i.e. type Foo = /*...*/ Returns the second argument.

func (*Comp) DeclTypeAlias0

func (c *Comp) DeclTypeAlias0(alias string, t xr.Type) xr.Type

DeclTypeAlias0 declares a type alias in Go, types are computed only at compile time - no need for a runtime *Env

func (*Comp) DeclVar0

func (c *Comp) DeclVar0(name string, t xr.Type, init *Expr) *Bind

DeclVar0 compiles a variable declaration. For caller's convenience, returns allocated Bind

func (*Comp) DeclVars

func (c *Comp) DeclVars(node ast.Spec)

DeclVars compiles a set of variable declarations i.e. "var x1, x2... [type] = expr1, expr2..."

func (*Comp) DeclVars0

func (c *Comp) DeclVars0(names []string, t xr.Type, inits []*Expr)

DeclVars0 compiles a set of variable declarations

func (*Comp) DeclVarsShort

func (c *Comp) DeclVarsShort(lhs []ast.Expr, rhs []ast.Expr)

DeclVarsShort compiles a set of variable short declarations i.e. "x1, x2... := expr1, expr2..."

func (*Comp) Defer

func (c *Comp) Defer(node *ast.DeferStmt)

Defer compiles a "defer" statement

func (*Comp) Deref

func (c *Comp) Deref(addr *Expr) *Expr

Deref compiles unary operator * i.e. pointer dereference

func (*Comp) Eql

func (c *Comp) Eql(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) ErrorIfCompiled

func (c *Comp) ErrorIfCompiled(x interface{})

func (*Comp) Expr

func (c *Comp) Expr(in ast.Expr) *Expr

Expr compiles an expression

func (*Comp) Expr1

func (c *Comp) Expr1(in ast.Expr) *Expr

Expr compiles an expression that returns a single value

func (*Comp) Expr1OrType

func (c *Comp) Expr1OrType(node ast.Expr) (e *Expr, t xr.Type)

Expr1OrType compiles an single-valued expression or a type FIXME lookup simultaneously for both types and expressions

func (*Comp) Exprs

func (c *Comp) Exprs(nodes []ast.Expr) []*Expr

Exprs compiles multiple expressions

func (*Comp) ExprsMultipleValues

func (c *Comp) ExprsMultipleValues(nodes []ast.Expr, expectedValuesN int) (inits []*Expr)

ExprsMultipleValues either a single expression returning multiple values, or multiple expressions each returning a value.

func (*Comp) File

func (c *Comp) File(node *ast.File)

func (*Comp) FileComp

func (c *Comp) FileComp() *Comp

func (*Comp) For

func (c *Comp) For(node *ast.ForStmt, labels []string)

For compiles a "for" statement

func (*Comp) FuncDecl

func (c *Comp) FuncDecl(funcdecl *ast.FuncDecl)

DeclFunc compiles a function, macro or method declaration For closure declarations, use FuncLit()

func (*Comp) FuncLit

func (c *Comp) FuncLit(funclit *ast.FuncLit) *Expr

FuncLit compiles a function literal, i.e. a closure. For functions or methods declarations, use FuncDecl()

func (*Comp) GenDecl

func (c *Comp) GenDecl(node *ast.GenDecl)

GenDecl compiles a constant, variable or type declaration - or an import

func (*Comp) Geq

func (c *Comp) Geq(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) GetPlace

func (c *Comp) GetPlace(place *Place) *Expr

func (*Comp) Go

func (c *Comp) Go(node *ast.GoStmt)

Go compiles a "go" statement i.e. a goroutine

func (*Comp) Gtr

func (c *Comp) Gtr(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Ident

func (c *Comp) Ident(name string) *Expr

Ident compiles a read operation on a constant, variable or function

func (*Comp) IdentPlace

func (c *Comp) IdentPlace(name string, opt PlaceOption) *Place

IdentPlace compiles an assignment to a variable, or taking the address of a variable

func (*Comp) If

func (c *Comp) If(node *ast.IfStmt)

If compiles an "if" statement

func (*Comp) Import

func (c *Comp) Import(node ast.Spec)

Import compiles an import statement

func (*Comp) ImportPackage

func (c *Comp) ImportPackage(name, path string) *Import

Import imports a package. Usually invoked as Comp.FileComp().ImportPackage(name, path) because imports are usually top-level statements in a source file. But we also support local imports, i.e. import statements inside a function or block.

func (*Comp) IncDec

func (c *Comp) IncDec(node *ast.IncDecStmt)

IncDec compiles a "place++" or "place--" statement

func (*Comp) IndexExpr

func (c *Comp) IndexExpr(node *ast.IndexExpr) *Expr

func (*Comp) IndexExpr1

func (c *Comp) IndexExpr1(node *ast.IndexExpr) *Expr

func (*Comp) IndexPlace

func (c *Comp) IndexPlace(node *ast.IndexExpr, opt PlaceOption) *Place

func (*Comp) InterfaceProxy

func (c *Comp) InterfaceProxy(t xr.Type) r.Type

InterfaceProxy returns the proxy struct that implements a compiled interface

func (*Comp) IsCompiled

func (c *Comp) IsCompiled() bool

func (*Comp) IsCompiledOuter

func (c *Comp) IsCompiledOuter(upn int) bool

func (*Comp) Land

func (c *Comp) Land(node *ast.BinaryExpr, x *Expr, y *Expr) *Expr

func (*Comp) Leq

func (c *Comp) Leq(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) List

func (c *Comp) List(list []ast.Stmt)

List compiles a slice of statements

func (*Comp) LookupField

func (c *Comp) LookupField(t xr.Type, name string) (field xr.StructField, numfound int)

LookupField performs a breadth-first search for struct field with given name

func (*Comp) LookupFieldOrMethod

func (c *Comp) LookupFieldOrMethod(t xr.Type, name string) (xr.StructField, bool, xr.Method, bool)

lookup fields and methods at the same time... it's and error if both exist at the same depth

func (*Comp) LookupMethod

func (c *Comp) LookupMethod(t xr.Type, name string) (mtd xr.Method, numfound int)

LookupMethod performs a breadth-first search for method with given name

func (*Comp) LookupVar

func (c *Comp) LookupVar(name string) *Var

LookupVar compiles the left-hand-side of an assignment, in case it's an identifier (i.e. a variable name)

func (*Comp) Lor

func (c *Comp) Lor(node *ast.BinaryExpr, x *Expr, y *Expr) *Expr

func (*Comp) Lss

func (c *Comp) Lss(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) MacroExpand

func (c *Comp) MacroExpand(form Ast) (out Ast, everExpanded bool)

MacroExpand repeatedly invokes MacroExpand as long as the node represents a macro call. it returns the resulting node.

func (*Comp) MacroExpand1

func (c *Comp) MacroExpand1(in Ast) (out Ast, expanded bool)

if node represents a macro call, MacroExpandNode1 executes it and returns the resulting node. Otherwise returns the node argument unchanged

func (*Comp) MacroExpandCodewalk

func (c *Comp) MacroExpandCodewalk(in Ast) (out Ast, anythingExpanded bool)

MacroExpandCodewalk traverses the whole AST tree using pre-order traversal, and replaces each node with the result of MacroExpand(node). It implements the macroexpansion phase

func (*Comp) MacroExpandNode

func (c *Comp) MacroExpandNode(in ast.Node) (out ast.Node, everExpanded bool)

MacroExpandNode repeatedly invokes MacroExpandNode1 as long as the node represents a macro call. it returns the resulting node.

func (*Comp) MacroExpandNode1

func (c *Comp) MacroExpandNode1(in ast.Node) (out ast.Node, expanded bool)

if node represents a macro call, MacroExpandNode1 executes it and returns the resulting node. Otherwise returns the node argument unchanged

func (*Comp) MacroExpandNodeCodewalk

func (c *Comp) MacroExpandNodeCodewalk(in ast.Node) (out ast.Node, anythingExpanded bool)

MacroExpandNodeCodewalk traverses the whole AST tree using pre-order traversal, and replaces each node with the result of MacroExpandNode(node). It implements the macroexpansion phase

func (*Comp) Mul

func (c *Comp) Mul(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Neq

func (c *Comp) Neq(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Or

func (c *Comp) Or(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Parse

func (c *Comp) Parse(src string) Ast

combined Parse + MacroExpandCodeWalk

func (*Comp) Place

func (c *Comp) Place(node ast.Expr) *Place

Place compiles the left-hand-side of an assignment

func (*Comp) Quasiquote

func (c *Comp) Quasiquote(in Ast) *Expr

Quasiquote expands and compiles ~quasiquote, if Ast starts with it

func (*Comp) Quo

func (c *Comp) Quo(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Range

func (c *Comp) Range(node *ast.RangeStmt, labels []string)

Range compiles a "for-range" statement

func (*Comp) Recv

func (c *Comp) Recv(node *ast.UnaryExpr, xe *Expr) *Expr

func (*Comp) Recv1

func (c *Comp) Recv1(node *ast.UnaryExpr, xe *Expr) *Expr

func (*Comp) Rem

func (c *Comp) Rem(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Resolve

func (c *Comp) Resolve(name string) *Symbol

func (*Comp) Return

func (c *Comp) Return(node *ast.ReturnStmt)

Return compiles a "return" statement

func (*Comp) Select

func (c *Comp) Select(node *ast.SelectStmt, labels []string)

func (*Comp) SelectorExpr

func (c *Comp) SelectorExpr(node *ast.SelectorExpr) *Expr

SelectorExpr compiles foo.bar, i.e. read access to methods, struct fields and imported packages

func (*Comp) SelectorPlace

func (c *Comp) SelectorPlace(node *ast.SelectorExpr, opt PlaceOption) *Place

SelectorPlace compiles a.b returning a settable and/or addressable Place

func (*Comp) Send

func (c *Comp) Send(node *ast.SendStmt)

func (*Comp) SetPlace

func (c *Comp) SetPlace(place *Place, op token.Token, init *Expr)

func (*Comp) SetUnderlyingType

func (c *Comp) SetUnderlyingType(t, underlying xr.Type)

func (*Comp) SetVar

func (c *Comp) SetVar(va *Var, op token.Token, init *Expr)

func (*Comp) ShiftUntyped

func (c *Comp) ShiftUntyped(node *ast.BinaryExpr, op token.Token, x UntypedLit, y UntypedLit) *Expr

func (*Comp) Shl

func (c *Comp) Shl(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Shr

func (c *Comp) Shr(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) SliceExpr

func (c *Comp) SliceExpr(node *ast.SliceExpr) *Expr

SliceExpr compiles slice[lo:hi] and slice[lo:hi:max]

func (*Comp) StarExpr

func (c *Comp) StarExpr(node *ast.StarExpr) *Expr

StarExpr compiles unary operator * i.e. pointer dereference

func (*Comp) Stmt

func (c *Comp) Stmt(in ast.Stmt)

func (*Comp) Sub

func (c *Comp) Sub(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

func (*Comp) Switch

func (c *Comp) Switch(node *ast.SwitchStmt, labels []string)

func (*Comp) Symbol

func (c *Comp) Symbol(sym *Symbol) *Expr

Symbol compiles a read operation on a constant, variable or function

func (*Comp) TopComp

func (c *Comp) TopComp() *Comp

func (*Comp) TryResolve

func (c *Comp) TryResolve(name string) *Symbol

func (*Comp) Type

func (c *Comp) Type(node ast.Expr) xr.Type

Type compiles a type expression.

func (*Comp) TypeArray

func (c *Comp) TypeArray(node *ast.ArrayType) (t xr.Type, ellipsis bool)

func (*Comp) TypeAssert1

func (c *Comp) TypeAssert1(node *ast.TypeAssertExpr) *Expr

TypeAssert1 compiles a single-valued type assertion

func (*Comp) TypeAssert2

func (c *Comp) TypeAssert2(node *ast.TypeAssertExpr) *Expr

TypeAssert2 compiles a multi-valued type assertion

func (*Comp) TypeFields

func (c *Comp) TypeFields(fields *ast.FieldList) (types []xr.Type, names []string)

func (*Comp) TypeFunction

func (c *Comp) TypeFunction(node *ast.FuncType) (t xr.Type, paramNames []string, resultNames []string)

func (*Comp) TypeFunctionOrMethod

func (c *Comp) TypeFunctionOrMethod(recv *ast.Field, node *ast.FuncType) (t xr.Type, paramNames []string, resultNames []string)

TypeFunctionOrMethod compiles a function type corresponding to given receiver and function declaration If receiver is not null, the returned tFunc will have it as receiver.

func (*Comp) TypeIdent

func (c *Comp) TypeIdent(name string) xr.Type

func (*Comp) TypeInterface

func (c *Comp) TypeInterface(node *ast.InterfaceType) xr.Type

func (*Comp) TypeOf

func (c *Comp) TypeOf(val interface{}) xr.Type

replacement of reflect.TypeOf() that uses xreflect.TypeOf()

func (*Comp) TypeSwitch

func (c *Comp) TypeSwitch(node *ast.TypeSwitchStmt, labels []string)

func (*Comp) UnaryExpr

func (c *Comp) UnaryExpr(node *ast.UnaryExpr) *Expr

func (*Comp) UnaryExprUntyped

func (c *Comp) UnaryExprUntyped(node *ast.UnaryExpr, xe *Expr) *Expr

func (*Comp) UnaryMinus

func (c *Comp) UnaryMinus(node *ast.UnaryExpr, xe *Expr) *Expr

func (*Comp) UnaryNot

func (c *Comp) UnaryNot(node *ast.UnaryExpr, xe *Expr) *Expr

func (*Comp) UnaryPlus

func (c *Comp) UnaryPlus(node *ast.UnaryExpr, xe *Expr) *Expr

func (*Comp) UnaryXor

func (c *Comp) UnaryXor(node *ast.UnaryExpr, xe *Expr) *Expr

func (*Comp) Xor

func (c *Comp) Xor(node *ast.BinaryExpr, xe *Expr, ye *Expr) *Expr

type CompThreadGlobals

type CompThreadGlobals struct {
	Universe *xr.Universe

	*Globals
	// contains filtered or unexported fields
}

CompGlobals contains per-goroutine interpreter compile bookeeping information

func (*CompThreadGlobals) TypeOfBool

func (g *CompThreadGlobals) TypeOfBool() xr.Type

func (*CompThreadGlobals) TypeOfBuiltin

func (g *CompThreadGlobals) TypeOfBuiltin() xr.Type

func (*CompThreadGlobals) TypeOfComplex64

func (g *CompThreadGlobals) TypeOfComplex64() xr.Type

func (*CompThreadGlobals) TypeOfComplex128

func (g *CompThreadGlobals) TypeOfComplex128() xr.Type

func (*CompThreadGlobals) TypeOfError

func (g *CompThreadGlobals) TypeOfError() xr.Type

func (*CompThreadGlobals) TypeOfFloat32

func (g *CompThreadGlobals) TypeOfFloat32() xr.Type

func (*CompThreadGlobals) TypeOfFloat64

func (g *CompThreadGlobals) TypeOfFloat64() xr.Type

func (*CompThreadGlobals) TypeOfFunction

func (g *CompThreadGlobals) TypeOfFunction() xr.Type

func (*CompThreadGlobals) TypeOfImport

func (g *CompThreadGlobals) TypeOfImport() xr.Type

func (*CompThreadGlobals) TypeOfInt

func (g *CompThreadGlobals) TypeOfInt() xr.Type

func (*CompThreadGlobals) TypeOfInt8

func (g *CompThreadGlobals) TypeOfInt8() xr.Type

func (*CompThreadGlobals) TypeOfInt16

func (g *CompThreadGlobals) TypeOfInt16() xr.Type

func (*CompThreadGlobals) TypeOfInt32

func (g *CompThreadGlobals) TypeOfInt32() xr.Type

func (*CompThreadGlobals) TypeOfInt64

func (g *CompThreadGlobals) TypeOfInt64() xr.Type

func (*CompThreadGlobals) TypeOfInterface

func (g *CompThreadGlobals) TypeOfInterface() xr.Type

func (*CompThreadGlobals) TypeOfMacro

func (g *CompThreadGlobals) TypeOfMacro() xr.Type

func (*CompThreadGlobals) TypeOfString

func (g *CompThreadGlobals) TypeOfString() xr.Type

func (*CompThreadGlobals) TypeOfUint

func (g *CompThreadGlobals) TypeOfUint() xr.Type

func (*CompThreadGlobals) TypeOfUint8

func (g *CompThreadGlobals) TypeOfUint8() xr.Type

func (*CompThreadGlobals) TypeOfUint16

func (g *CompThreadGlobals) TypeOfUint16() xr.Type

func (*CompThreadGlobals) TypeOfUint32

func (g *CompThreadGlobals) TypeOfUint32() xr.Type

func (*CompThreadGlobals) TypeOfUint64

func (g *CompThreadGlobals) TypeOfUint64() xr.Type

func (*CompThreadGlobals) TypeOfUintptr

func (g *CompThreadGlobals) TypeOfUintptr() xr.Type

func (*CompThreadGlobals) TypeOfUntypedLit

func (g *CompThreadGlobals) TypeOfUntypedLit() xr.Type

type CompileOptions

type CompileOptions int
const (
	OptKeepUntyped CompileOptions = 1 << iota // if set, Compile() on expressions will keep all untyped constants as such (in expressions where Go compiler would compute an untyped constant too)
	OptIsCompiled                             // if set, packages is at least partially compiled. Effect: variables may be pre-existing, so Comp.intBinds cannot be used
	OptDefaults    CompileOptions = 0
)

func (CompileOptions) IsCompiled

func (opts CompileOptions) IsCompiled() bool

type EFlags

type EFlags uint32

EFlags represents the flags of an expression

const (
	EIsNil EFlags = 1 << iota
	EIsTypeAssert
)

func EFlag4Value

func EFlag4Value(value I) EFlags

func MakeEFlag

func MakeEFlag(flag bool, iftrue EFlags) EFlags

func (EFlags) IsNil

func (f EFlags) IsNil() bool

type Env

type Env struct {
	Binds         []r.Value
	IntBinds      []uint64
	Outer         *Env
	IP            int
	Code          []Stmt
	DebugPos      []token.Pos // for debugging interpreted code: position of each statement
	ThreadGlobals *ThreadGlobals
	UsedByClosure bool // a bitfield would introduce more races among goroutines
	AddressTaken  bool // true if &Env.IntBinds[index] was executed... then we cannot reuse IntBinds
}

Env is the interpreter's runtime environment

func NewEnv

func NewEnv(outer *Env, nbinds int, nintbinds int) *Env

func NewEnv4Func

func NewEnv4Func(outer *Env, nbinds int, nintbinds int) *Env

func (*Env) File

func (env *Env) File() *Env

func (*Env) FreeEnv

func (env *Env) FreeEnv()

FreeEnv tells the interpreter that given Env is no longer needed.

func (*Env) MarkUsedByClosure

func (env *Env) MarkUsedByClosure()

func (*Env) Top

func (env *Env) Top() *Env

type Expr

type Expr struct {
	Lit
	Types []xr.Type // in case the expression produces multiple values. if nil, use Lit.Type.
	Fun   I         // function that evaluates the expression at runtime.
	Sym   *Symbol   // in case the expression is a symbol
	EFlags
}

Expr represents an expression in the "compiler"

func (*Expr) AsStmt

func (e *Expr) AsStmt() Stmt

func (*Expr) AsX

func (e *Expr) AsX() func(*Env)

func (*Expr) AsX1

func (e *Expr) AsX1() func(*Env) r.Value

func (*Expr) AsXV

func (e *Expr) AsXV(opts CompileOptions) func(*Env) (r.Value, []r.Value)

func (*Expr) CheckX1

func (e *Expr) CheckX1()

CheckX1() panics if given expression cannot be used in single-value context, for example because it returns no value at all. It just prints a warning if expression returns multiple values.

func (*Expr) Const

func (e *Expr) Const() bool

func (*Expr) ConstTo

func (e *Expr) ConstTo(t xr.Type) I

ConstTo checks that a constant Expr can be used as the given type. panics if not constant, or if Expr is a typed constant of different type actually performs type conversion (and subsequent overflow checks) ONLY on untyped constants.

func (*Expr) DefaultType

func (e *Expr) DefaultType() xr.Type

DefaultType returns the default type of an expression.

func (*Expr) EvalConst

func (expr *Expr) EvalConst(opts CompileOptions) I

func (*Expr) NumOut

func (e *Expr) NumOut() int

NumOut returns the number of values that an expression will produce when evaluated

func (*Expr) Out

func (e *Expr) Out(i int) xr.Type

Out returns the i-th type that an expression will produce when evaluated

func (*Expr) Outs

func (e *Expr) Outs() []xr.Type

Outs returns the types that an expression will produce when evaluated

func (*Expr) SetTypes

func (e *Expr) SetTypes(tout []xr.Type)

SetTypes sets the expression result types

func (*Expr) String

func (e *Expr) String() string

func (*Expr) To

func (e *Expr) To(c *Comp, t xr.Type)

To checks that an Expr can be used as (i.e. is assignable to) the given type, and converts Expr to the given type. panics if Expr has an incompatible type.

func (*Expr) TryAsPred

func (e *Expr) TryAsPred() (value bool, fun func(*Env) bool, err bool)

func (*Expr) WithFun

func (e *Expr) WithFun() I

WithFun ensures that Expr.Fun is a closure that will return the expression result:

if Expr is an untyped constant, WithFun converts the constant to its default type (panics on overflows),

then sets Expr.Fun to a closure that will return such constant.

if Expr is a typed constant, WithFun sets Expr.Fun to a closure that will return such constant. if Expr is not a constant, WithFun does nothing (Expr.Fun must be set already)

type FuncInfo

type FuncInfo struct {
	Params       []*Bind
	Results      []*Bind
	NamedResults bool
}

type Function

type Function struct {
	Fun  interface{}
	Type xr.Type
}

Function represents a function that accesses *CompEnv in the fast interpreter

type I

type I interface{}

type I_github_com_cosmos72_gomacro_fast

type I_github_com_cosmos72_gomacro_fast struct {
	Object interface{}
}

--------------- proxy for github.com/cosmos72/gomacro/fast.I ---------------

type Import

type Import struct {
	// no need to split compile-time bind descriptors map from runtime values slice,
	// because an import is a singleton - cannot be "instantiated" multiple times.
	// Instead function or block activation record (*Env) can:
	// think about goroutines, recursive functions or even loops.
	Binds      map[string]r.Value
	BindTypes  map[string]xr.Type
	Types      map[string]xr.Type
	Name, Path string
}

Import represents an imported package

type Interp

type Interp struct {
	Comp *Comp
	// contains filtered or unexported fields
}

Interp is the fast interpreter. It contains both the tree-of-closures builder Comp and the interpreter's runtime environment Env

func New

func New() *Interp

func NewCompEnv

func NewCompEnv(outer *Interp, path string) *Interp

func NewCompEnvTop

func NewCompEnvTop(path string) *Interp

func (*Interp) AddressOfVar

func (ir *Interp) AddressOfVar(name string) (addr r.Value)

AddressOfVar compiles the expression &name, then executes it returns the zero value if name is not found or is not addressable

func (*Interp) ChangePackage

func (ir *Interp) ChangePackage(name, path string)

func (*Interp) Compile

func (ir *Interp) Compile(src string) *Expr

combined Parse + Compile

func (*Interp) CompileAst

func (ir *Interp) CompileAst(form ast2.Ast) *Expr

func (*Interp) CompileNode

func (ir *Interp) CompileNode(node ast.Node) *Expr

func (*Interp) DeclBuiltin

func (ir *Interp) DeclBuiltin(name string, builtin Builtin)

DeclBuiltin compiles a builtin function declaration

func (*Interp) DeclConst

func (ir *Interp) DeclConst(name string, t xr.Type, value I)

DeclConst compiles a constant declaration

func (*Interp) DeclEnvFunc

func (ir *Interp) DeclEnvFunc(name string, function Function)

DeclEnvFunc compiles a function declaration that accesses interpreter's *CompEnv

func (*Interp) DeclFunc

func (ir *Interp) DeclFunc(name string, fun I)

DeclFunc compiles a function declaration

func (*Interp) DeclType

func (ir *Interp) DeclType(t xr.Type)

DeclType declares a type

func (*Interp) DeclTypeAlias

func (ir *Interp) DeclTypeAlias(alias string, t xr.Type)

DeclType declares a type alias

func (*Interp) DeclVar

func (ir *Interp) DeclVar(name string, t xr.Type, value I)

DeclVar compiles a variable declaration

func (*Interp) Eval

func (ir *Interp) Eval(src string) (r.Value, []r.Value)

combined Parse + Compile + RunExpr

func (*Interp) Parse

func (ir *Interp) Parse(src string) ast2.Ast

func (*Interp) PrepareEnv

func (ir *Interp) PrepareEnv() *Env

func (*Interp) RunExpr

func (ir *Interp) RunExpr(e *Expr) (r.Value, []r.Value)

func (*Interp) RunExpr1

func (ir *Interp) RunExpr1(e *Expr) r.Value

func (*Interp) TypeOf

func (ir *Interp) TypeOf(val interface{}) xr.Type

replacement of reflect.TypeOf() that uses xreflect.TypeOf()

func (*Interp) ValueOf

func (ir *Interp) ValueOf(name string) (value r.Value)

ValueOf retrieves the value of a constant, function or variable The returned value is settable and addressable only for variables returns the zero value if name is not found

type Lit

type Lit struct {

	// Type is nil only for literal nils.
	// for all other literals, it is reflect.TypeOf(Lit.Value)
	//
	// when Lit is embedded in other structs that represent non-constant expressions,
	// Type is the first type returned by the expression (nil if returns no values)
	Type xr.Type

	// Value is one of:
	//   nil, bool, int, int8, int16, int32, int64,
	//   uint, uint8, uint16, uint32, uint64, uintptr,
	//   float32, float64, complex64, complex128, string,
	//   UntypedLit
	//
	// when Lit is embedded in other structs that represent non-constant expressions,
	// Value is usually nil
	Value I
}

Lit represents a literal value, i.e. a typed or untyped constant

func (*Lit) ConstTo

func (lit *Lit) ConstTo(t xr.Type) I

ConstTo checks that a Lit can be used as the given type. panics if Lit is a typed constant of different type actually performs type conversion (and subsequent overflow checks) ONLY on untyped constants.

func (*Lit) DefaultType

func (lit *Lit) DefaultType() xr.Type

DefaultType returns the default type of a constant.

func (*Lit) ReflectValue

func (lit *Lit) ReflectValue() r.Value

func (Lit) String

func (lit Lit) String() string

func (*Lit) Untyped

func (lit *Lit) Untyped() bool

Untyped returns true if Lit is an untyped constant

func (*Lit) UntypedKind

func (lit *Lit) UntypedKind() r.Kind

UntypedKind returns the reflect.Kind of untyped constants, i.e. their "default type"

type LoopInfo

type LoopInfo struct {
	Break      *int
	Continue   *int
	Labels     map[string]*int
	ThisLabels []string // sorted. for labeled "switch" and "for"
}

func (*LoopInfo) HasLabel

func (l *LoopInfo) HasLabel(label string) bool

type Macro

type Macro struct {
	// contains filtered or unexported fields
}

Macro represents a macro in the fast interpreter

type NamedType

type NamedType struct {
	Name, Path string
}

type Place

type Place struct {
	Var
	// Fun is nil for variables.
	// For non-variables, returns a settable and addressable reflect.Value: the place itself.
	// For map[key], Fun returns the map itself (which may NOT be settable).
	// Call Fun only once, it may have side effects!
	Fun func(*Env) r.Value
	// Fddr is nil for variables.
	// For non-variables, it will return the address of the place.
	// For map[key], it is nil since map[key] is not addressable
	// Call Addr only once, it may have side effects!
	Addr func(*Env) r.Value
	// used only for map[key], returns key. call it only once, it may have side effects!
	MapKey  func(*Env) r.Value
	MapType xr.Type
}

Place represents a settable place or, equivalently, its address

func (*Place) IsVar

func (place *Place) IsVar() bool

type PlaceOption

type PlaceOption bool // the reason why we want a place: either to write into it, or to take its address
const (
	PlaceSettable PlaceOption = false
	PlaceAddress  PlaceOption = true
)

func (PlaceOption) String

func (opt PlaceOption) String() string

type Signal

type Signal int
const (
	SigNone Signal = iota
	SigReturn
	SigDefer // request to install a defer function
)

type Stmt

type Stmt func(*Env) (Stmt, *Env)

Stmt represents a statement in the fast interpreter

var Interrupt Stmt = func(env *Env) (Stmt, *Env) {
	return env.ThreadGlobals.Interrupt, env
}

declare a var instead of function: Code.Exec() needs the address of Interrupt

type Symbol

type Symbol struct {
	Bind
	Upn int
}

Symbol represents a resolved constant, function, variable or builtin

func (*Symbol) AsVar

func (sym *Symbol) AsVar(opt PlaceOption) *Var

type ThreadGlobals

type ThreadGlobals struct {
	FileEnv      *Env
	TopEnv       *Env
	Interrupt    Stmt
	Signal       Signal // set by interrupts: Return, Defer...
	PoolSize     int
	Pool         [PoolCapacity]*Env
	InstallDefer func()      // defer function to be installed
	Panic        interface{} // current panic. needed for recover()
	PanicFun     *Env        // the currently panicking function
	DeferOfFun   *Env        // function whose defer are running
	StartDefer   bool        // true if next executed function body is a defer
	IsDefer      bool        // true if function body being executed is a defer
	*Globals
}

ThreadGlobals contains per-goroutine interpreter runtime bookeeping information

func NewThreadGlobals

func NewThreadGlobals() *ThreadGlobals

type TypeAssertionError

type TypeAssertionError struct {
	Interface     r.Type
	Concrete      r.Type
	Asserted      r.Type
	MissingMethod string // one method needed by Interface, missing from Concrete
}

A TypeAssertionError explains a failed type assertion.

func (*TypeAssertionError) Error

func (e *TypeAssertionError) Error() string

func (*TypeAssertionError) RuntimeError

func (*TypeAssertionError) RuntimeError()

type UntypedLit

type UntypedLit struct {
	Kind     r.Kind // default type. matches Obj.Kind() except for rune literals, where Kind == reflect.Int32
	Obj      constant.Value
	Universe *xr.Universe
}

UntypedLit represents an untyped literal value, i.e. an untyped constant

func (*UntypedLit) ConstTo

func (untyp *UntypedLit) ConstTo(t xr.Type) I

ConstTo checks that an UntypedLit can be used as the given type. performs actual untyped -> typed conversion and subsequent overflow checks. returns the constant converted to given type

func (*UntypedLit) DefaultType

func (untyp *UntypedLit) DefaultType() xr.Type

DefaultType returns the default type of an untyped constant.

func (*UntypedLit) IsLiteralNumber

func (untyp *UntypedLit) IsLiteralNumber(n int64) bool

func (UntypedLit) String

func (untyp UntypedLit) String() string

pretty-print untyped constants

type Var

type Var struct {
	// when Var is embedded in other structs that represent non-identifiers,
	// Upn and Desc are usually the zero values
	Upn  int
	Desc BindDescriptor
	Type xr.Type
	Name string
}

Var represents a settable variable

func (*Var) Address

func (va *Var) Address(maxdepth int) *Expr

func (*Var) AsPlace

func (va *Var) AsPlace() *Place

func (*Var) AsSymbol

func (va *Var) AsSymbol() *Symbol

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL