LLVMIn/OutType stuff, not sure if I'll keep it
This commit is contained in:
parent
3b6fe4fb4a
commit
45ce802b35
152
expr/expr.go
152
expr/expr.go
@ -24,6 +24,12 @@ type LLVMCtx struct {
|
|||||||
// properties. It is wrapped by Expr which also holds onto contextual
|
// properties. It is wrapped by Expr which also holds onto contextual
|
||||||
// information, like the token to which Actual was originally parsed from
|
// information, like the token to which Actual was originally parsed from
|
||||||
type Actual interface {
|
type Actual interface {
|
||||||
|
// Returns the llvm.Type which the expression accepts as an input, if any
|
||||||
|
LLVMInType(ctx *Ctx) llvm.Type
|
||||||
|
|
||||||
|
// Returns the llvm.Type which the expressions outputs
|
||||||
|
LLVMOutType(ctx *Ctx) llvm.Type
|
||||||
|
|
||||||
// Initializes an llvm.Value and returns it.
|
// Initializes an llvm.Value and returns it.
|
||||||
LLVMVal(*Ctx, LLVMCtx) llvm.Value
|
LLVMVal(*Ctx, LLVMCtx) llvm.Value
|
||||||
}
|
}
|
||||||
@ -46,6 +52,16 @@ type Expr struct {
|
|||||||
val *llvm.Value
|
val *llvm.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LLVMInType passes through to the method on the underlying Actual
|
||||||
|
func (e Expr) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
return e.Actual.LLVMInType(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType passes through to the method on the underlying Actual
|
||||||
|
func (e Expr) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
return e.Actual.LLVMOutType(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal passes its arguments to the underlying Actual instance. It caches the
|
// LLVMVal passes its arguments to the underlying Actual instance. It caches the
|
||||||
// result, so if this is called multiple times the underlying one is only called
|
// result, so if this is called multiple times the underlying one is only called
|
||||||
// the first time.
|
// the first time.
|
||||||
@ -69,9 +85,41 @@ func (e Expr) equal(e2 Expr) bool {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Void represents no data (size = 0)
|
||||||
|
type Void struct{}
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (v Void) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("Void has no InType")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (v Void) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
return llvm.VoidType()
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMVal implements the Actual interface method
|
||||||
|
func (v Void) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
|
// Kind of weird that this only works for return type, but I guess makes
|
||||||
|
// sense
|
||||||
|
return lctx.B.CreateRetVoid()
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Bool represents a true or false value
|
// Bool represents a true or false value
|
||||||
type Bool bool
|
type Bool bool
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (b Bool) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("Bool has no InType")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (b Bool) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
return llvm.IntType(1)
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
// LLVMVal implements the Actual interface method
|
||||||
func (b Bool) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (b Bool) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
return llvm.Value{}
|
return llvm.Value{}
|
||||||
@ -90,6 +138,16 @@ func (b Bool) equal(e equaler) bool {
|
|||||||
// Int represents an integer value
|
// Int represents an integer value
|
||||||
type Int int64
|
type Int int64
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (i Int) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("Int has no InType")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (i Int) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
return llvm.Int64Type()
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
// LLVMVal implements the Actual interface method
|
||||||
func (i Int) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (i Int) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
v := lctx.B.CreateAlloca(llvm.Int64Type(), "")
|
v := lctx.B.CreateAlloca(llvm.Int64Type(), "")
|
||||||
@ -110,9 +168,19 @@ func (i Int) equal(e equaler) bool {
|
|||||||
// String represents a string value
|
// String represents a string value
|
||||||
type String string
|
type String string
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (s String) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("String has no InType")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (s String) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
// LLVMVal implements the Actual interface method
|
||||||
func (s String) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (s String) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
return llvm.Value{}
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s String) equal(e equaler) bool {
|
func (s String) equal(e equaler) bool {
|
||||||
@ -129,9 +197,19 @@ func (s String) equal(e equaler) bool {
|
|||||||
// name
|
// name
|
||||||
type Identifier string
|
type Identifier string
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (id Identifier) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (id Identifier) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
// LLVMVal implements the Actual interface method
|
||||||
func (id Identifier) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (id Identifier) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
return llvm.Value{}
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (id Identifier) equal(e equaler) bool {
|
func (id Identifier) equal(e equaler) bool {
|
||||||
@ -154,9 +232,19 @@ func (m Macro) String() string {
|
|||||||
return "%" + string(m)
|
return "%" + string(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (m Macro) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("Macro has no InType")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (m Macro) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("Macro has no OutType")
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
// LLVMVal implements the Actual interface method
|
||||||
func (m Macro) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (m Macro) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
panic("Macros have no inherent LLVMVal")
|
panic("Macro has no Val")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Macro) equal(e equaler) bool {
|
func (m Macro) equal(e equaler) bool {
|
||||||
@ -181,9 +269,19 @@ func (tup Tuple) String() string {
|
|||||||
return "(" + strings.Join(strs, ", ") + ")"
|
return "(" + strings.Join(strs, ", ") + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (tup Tuple) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (tup Tuple) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
// LLVMVal implements the Actual interface method
|
||||||
func (tup Tuple) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (tup Tuple) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
return llvm.Value{}
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tup Tuple) equal(e equaler) bool {
|
func (tup Tuple) equal(e equaler) bool {
|
||||||
@ -213,25 +311,47 @@ func (s Statement) String() string {
|
|||||||
return fmt.Sprintf("(%v > %s)", s.In.Actual, s.To.Actual)
|
return fmt.Sprintf("(%v > %s)", s.In.Actual, s.To.Actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
func (s Statement) maybeMacro(ctx *Ctx) (Expr, bool) {
|
||||||
func (s Statement) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
|
||||||
m, ok := s.To.Actual.(Macro)
|
m, ok := s.To.Actual.(Macro)
|
||||||
if !ok {
|
if !ok {
|
||||||
// TODO proper error
|
return Expr{}, false
|
||||||
panic("statement To is not a macro")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := ctx.GetMacro(m)
|
fn := ctx.GetMacro(m)
|
||||||
if fn == nil {
|
if fn == nil {
|
||||||
// TODO proper error
|
return Expr{}, false
|
||||||
panic(fmt.Sprintf("unknown macro %q", m))
|
|
||||||
}
|
}
|
||||||
newe, err := fn(s.In)
|
newe, err := fn(s.In)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO proper error
|
// TODO proper error
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return newe.LLVMVal(ctx, lctx)
|
return newe, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (s Statement) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
if newe, ok := s.maybeMacro(ctx); ok {
|
||||||
|
return newe.LLVMInType(ctx)
|
||||||
|
}
|
||||||
|
// TODO futures
|
||||||
|
panic("unknown Statement.To")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (s Statement) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
if newe, ok := s.maybeMacro(ctx); ok {
|
||||||
|
return newe.LLVMOutType(ctx)
|
||||||
|
}
|
||||||
|
panic("unknown Statement.To")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMVal implements the Actual interface method
|
||||||
|
func (s Statement) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
|
if newe, ok := s.maybeMacro(ctx); ok {
|
||||||
|
return newe.LLVMVal(ctx, lctx)
|
||||||
|
}
|
||||||
|
panic("unknown Statement.To")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Statement) equal(e equaler) bool {
|
func (s Statement) equal(e equaler) bool {
|
||||||
@ -254,6 +374,16 @@ func (b Block) String() string {
|
|||||||
return fmt.Sprintf("{ %s }", strings.Join(strs, " "))
|
return fmt.Sprintf("{ %s }", strings.Join(strs, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LLVMInType implements the Actual interface method
|
||||||
|
func (b Block) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLVMOutType implements the Actual interface method
|
||||||
|
func (b Block) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
return b[len(b)-1].LLVMOutType(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// LLVMVal implements the Actual interface method
|
// LLVMVal implements the Actual interface method
|
||||||
func (b Block) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (b Block) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
name := randStr() // TODO make this based on token
|
name := randStr() // TODO make this based on token
|
||||||
|
@ -8,6 +8,14 @@ import (
|
|||||||
|
|
||||||
type addActual []Expr
|
type addActual []Expr
|
||||||
|
|
||||||
|
func (aa addActual) LLVMInType(ctx *Ctx) llvm.Type {
|
||||||
|
panic("addActual has no InType")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aa addActual) LLVMOutType(ctx *Ctx) llvm.Type {
|
||||||
|
return aa[0].LLVMOutType(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (aa addActual) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
func (aa addActual) LLVMVal(ctx *Ctx, lctx LLVMCtx) llvm.Value {
|
||||||
a := lctx.B.CreateLoad(aa[0].LLVMVal(ctx, lctx), "")
|
a := lctx.B.CreateLoad(aa[0].LLVMVal(ctx, lctx), "")
|
||||||
for i := range aa[1:] {
|
for i := range aa[1:] {
|
||||||
|
Loading…
Reference in New Issue
Block a user