got macro statements working
This commit is contained in:
parent
fd125b3dcd
commit
da0d0dfc18
34
expr/expr.go
34
expr/expr.go
@ -26,7 +26,7 @@ type Actual interface {
|
|||||||
// are equal.
|
// are equal.
|
||||||
Equal(Actual) bool
|
Equal(Actual) bool
|
||||||
|
|
||||||
// Initializes an llvm.Value and returns it
|
// Initializes an llvm.Value and returns it.
|
||||||
LLVMVal(llvm.Builder) llvm.Value
|
LLVMVal(llvm.Builder) llvm.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ func (m Macro) Equal(e Actual) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m Macro) LLVMVal(builder llvm.Builder) llvm.Value {
|
func (m Macro) LLVMVal(builder llvm.Builder) llvm.Value {
|
||||||
return llvm.Value{}
|
panic("Macros have no inherent LLVMVal")
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -188,6 +188,8 @@ func (tup Tuple) LLVMVal(builder llvm.Builder) llvm.Value {
|
|||||||
// Pipe represents a set of expressions which operate on values and return new
|
// Pipe represents a set of expressions which operate on values and return new
|
||||||
// values. The inputs of one expression in the pipe is the output of the
|
// values. The inputs of one expression in the pipe is the output of the
|
||||||
// previous expression
|
// previous expression
|
||||||
|
//
|
||||||
|
// TODO remove this, sorry Pipe
|
||||||
type Pipe []Expr
|
type Pipe []Expr
|
||||||
|
|
||||||
func (p Pipe) String() string {
|
func (p Pipe) String() string {
|
||||||
@ -222,22 +224,37 @@ func (p Pipe) LLVMVal(builder llvm.Builder) llvm.Value {
|
|||||||
// used as the input to the pipe, and the output of the pipe is the output of
|
// used as the input to the pipe, and the output of the pipe is the output of
|
||||||
// the statement
|
// the statement
|
||||||
type Statement struct {
|
type Statement struct {
|
||||||
in Expr
|
In Expr
|
||||||
pipe Pipe
|
To Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Statement) String() string {
|
func (s Statement) String() string {
|
||||||
return fmt.Sprintf("(%v > %s)", s.in.Actual, s.pipe.String())
|
return fmt.Sprintf("(%v > %s)", s.In.Actual, s.To.Actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal implements the Actual method
|
// Equal implements the Actual method
|
||||||
func (s Statement) Equal(e Actual) bool {
|
func (s Statement) Equal(e Actual) bool {
|
||||||
ss, ok := e.(Statement)
|
ss, ok := e.(Statement)
|
||||||
return ok && s.in.Actual.Equal(ss.in.Actual) && s.pipe.Equal(ss.pipe)
|
return ok && s.In.Actual.Equal(ss.In.Actual) && s.To.Actual.Equal(ss.To.Actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Statement) LLVMVal(builder llvm.Builder) llvm.Value {
|
func (s Statement) LLVMVal(builder llvm.Builder) llvm.Value {
|
||||||
return llvm.Value{}
|
m, ok := s.To.Actual.(Macro)
|
||||||
|
if !ok {
|
||||||
|
// TODO proper error
|
||||||
|
panic("statement To is not a macro")
|
||||||
|
}
|
||||||
|
fn, ok := macros[m]
|
||||||
|
if !ok {
|
||||||
|
// TODO proper error
|
||||||
|
panic(fmt.Sprintf("unknown macro %q", m))
|
||||||
|
}
|
||||||
|
newe, err := fn(s.In)
|
||||||
|
if err != nil {
|
||||||
|
// TODO proper error
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return newe.LLVMVal(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -513,7 +530,8 @@ func parseConnectingPunct(toks []lexer.Token, root Expr) (Expr, []lexer.Token, e
|
|||||||
if !ok {
|
if !ok {
|
||||||
pipe = Pipe{expr}
|
pipe = Pipe{expr}
|
||||||
}
|
}
|
||||||
return Expr{Token: root.Token, Actual: Statement{in: root, pipe: pipe}}, toks, nil
|
pipeExpr := Expr{Actual: pipe, Token: expr.Token}
|
||||||
|
return Expr{Token: root.Token, Actual: Statement{In: root, To: pipeExpr}}, toks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return root, toks, nil
|
return root, toks, nil
|
||||||
|
34
expr/macros.go
Normal file
34
expr/macros.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package expr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"llvm.org/llvm/bindings/go/llvm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type addActual []Expr
|
||||||
|
|
||||||
|
func (aa addActual) Equal(Actual) bool { return false }
|
||||||
|
|
||||||
|
func (aa addActual) LLVMVal(builder llvm.Builder) llvm.Value {
|
||||||
|
a := builder.CreateLoad(aa[0].LLVMVal(builder), "")
|
||||||
|
for i := range aa[1:] {
|
||||||
|
b := builder.CreateLoad(aa[i+1].LLVMVal(builder), "")
|
||||||
|
a = builder.CreateAdd(a, b, "")
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
var macros = map[Macro]func(Expr) (Expr, error){
|
||||||
|
"add": func(e Expr) (Expr, error) {
|
||||||
|
tup, ok := e.Actual.(Tuple)
|
||||||
|
if !ok {
|
||||||
|
// TODO proper error
|
||||||
|
return Expr{}, errors.New("add only accepts a tuple")
|
||||||
|
}
|
||||||
|
return Expr{
|
||||||
|
Actual: addActual(tup),
|
||||||
|
Token: e.Token,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
}
|
20
main.go
20
main.go
@ -8,19 +8,6 @@ import (
|
|||||||
"llvm.org/llvm/bindings/go/llvm"
|
"llvm.org/llvm/bindings/go/llvm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type addActual []expr.Expr
|
|
||||||
|
|
||||||
func (aa addActual) Equal(expr.Actual) bool { return false }
|
|
||||||
|
|
||||||
func (aa addActual) LLVMVal(builder llvm.Builder) llvm.Value {
|
|
||||||
a := builder.CreateLoad(aa[0].LLVMVal(builder), "")
|
|
||||||
for i := range aa[1:] {
|
|
||||||
b := builder.CreateLoad(aa[i+1].LLVMVal(builder), "")
|
|
||||||
a = builder.CreateAdd(a, b, "")
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//ee, err := expr.Parse(os.Stdin)
|
//ee, err := expr.Parse(os.Stdin)
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
@ -47,8 +34,11 @@ func main() {
|
|||||||
a := expr.Expr{Actual: expr.Int(1)}
|
a := expr.Expr{Actual: expr.Int(1)}
|
||||||
b := expr.Expr{Actual: expr.Int(2)}
|
b := expr.Expr{Actual: expr.Int(2)}
|
||||||
c := expr.Expr{Actual: expr.Int(3)}
|
c := expr.Expr{Actual: expr.Int(3)}
|
||||||
add := addActual{a, b, c}
|
tup := expr.Expr{Actual: expr.Tuple{a, b, c}}
|
||||||
result := add.LLVMVal(builder)
|
addMacro := expr.Expr{Actual: expr.Macro("add")}
|
||||||
|
stmt := expr.Expr{Actual: expr.Statement{In: tup, To: addMacro}}
|
||||||
|
|
||||||
|
result := stmt.LLVMVal(builder)
|
||||||
builder.CreateRet(result)
|
builder.CreateRet(result)
|
||||||
|
|
||||||
// verify it's all good
|
// verify it's all good
|
||||||
|
Loading…
Reference in New Issue
Block a user