2016-07-29 00:39:18 +00:00
|
|
|
package expr
|
|
|
|
|
2016-08-05 18:34:17 +00:00
|
|
|
import "llvm.org/llvm/bindings/go/llvm"
|
|
|
|
|
2016-08-06 18:20:53 +00:00
|
|
|
// MacroFn is a compiler function which takes in an existing Expr and returns
|
|
|
|
// the llvm Value for it
|
|
|
|
type MacroFn func(BuildCtx, Expr) Expr
|
2016-08-05 18:34:17 +00:00
|
|
|
|
2016-08-06 18:20:53 +00:00
|
|
|
// Ctx contains all the Macros and Identifiers available. A Ctx also keeps a
|
|
|
|
// reference to the global context, which has a number of macros available for
|
|
|
|
// all contexts to use.
|
2016-07-29 00:39:18 +00:00
|
|
|
type Ctx struct {
|
2016-08-06 18:20:53 +00:00
|
|
|
global *Ctx
|
|
|
|
macros map[Macro]MacroFn
|
|
|
|
idents map[Identifier]llvm.Value
|
|
|
|
}
|
2016-08-05 18:34:17 +00:00
|
|
|
|
2016-08-06 18:20:53 +00:00
|
|
|
// NewCtx returns a blank context instance
|
|
|
|
func NewCtx() *Ctx {
|
|
|
|
return &Ctx{
|
|
|
|
global: globalCtx,
|
|
|
|
macros: map[Macro]MacroFn{},
|
|
|
|
idents: map[Identifier]llvm.Value{},
|
|
|
|
}
|
2016-07-29 00:39:18 +00:00
|
|
|
}
|
|
|
|
|
2016-08-06 18:20:53 +00:00
|
|
|
// GetMacro returns the MacroFn associated with the given identifier, or panics
|
|
|
|
// if the macro isn't found
|
2016-08-05 18:34:17 +00:00
|
|
|
func (c *Ctx) GetMacro(m Macro) MacroFn {
|
2016-08-06 18:20:53 +00:00
|
|
|
if fn := c.macros[m]; fn != nil {
|
|
|
|
return fn
|
2016-07-29 00:39:18 +00:00
|
|
|
}
|
2016-08-06 18:20:53 +00:00
|
|
|
if fn := c.global.macros[m]; fn != nil {
|
|
|
|
return fn
|
2016-07-29 00:39:18 +00:00
|
|
|
}
|
2016-08-06 18:20:53 +00:00
|
|
|
panicf("macro %q not found in context", m)
|
2016-07-29 00:39:18 +00:00
|
|
|
return nil
|
|
|
|
}
|
2016-08-06 18:20:53 +00:00
|
|
|
|
|
|
|
// GetIdentifier returns the llvm.Value for the Identifier, or panics
|
2016-08-06 18:36:46 +00:00
|
|
|
func (c *Ctx) GetIdentifier(i Identifier) (llvm.Value, bool) {
|
2016-08-06 18:20:53 +00:00
|
|
|
if v, ok := c.idents[i]; ok {
|
2016-08-06 18:36:46 +00:00
|
|
|
return v, true
|
2016-08-06 18:20:53 +00:00
|
|
|
}
|
|
|
|
// The global context doesn't have any identifiers, so don't bother checking
|
2016-08-06 18:36:46 +00:00
|
|
|
return llvm.Value{}, false
|
2016-08-06 18:20:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewWith returns a new Ctx instance which imports the given macros from the
|
|
|
|
// parent
|
|
|
|
//func (c *Ctx) NewWith(mm ...Macro) *Ctx {
|
|
|
|
// nc := &Ctx{
|
|
|
|
// global: c.global,
|
|
|
|
// macros: map[Macro]MacroFn{},
|
|
|
|
// }
|
|
|
|
// for _, m := range mm {
|
|
|
|
// fn := c.macros[m]
|
|
|
|
// if fn == nil {
|
|
|
|
// panicf("no macro %q found in context", m)
|
|
|
|
// }
|
|
|
|
// nc.macros[m] = fn
|
|
|
|
// }
|
|
|
|
// return nc
|
|
|
|
//}
|