get rid of pipe, sorry pipe
This commit is contained in:
parent
da0d0dfc18
commit
9c9c8afb7d
82
expr/expr.go
82
expr/expr.go
@ -17,6 +17,11 @@ import (
|
||||
// TODO having Equal as part of the Actual interface is going to be annoying.
|
||||
// The built in macros which return their own expressions don't really care
|
||||
// about it, and it's really only needed for tests I think.
|
||||
//
|
||||
// Alternatively, don't have token be embedded in the expression. I'm not sure
|
||||
// if that's actually possible.
|
||||
|
||||
// TODO need to figure out how to test LLVMVal stuff
|
||||
|
||||
// Actual represents the actual expression in question, and has certain
|
||||
// properties. It is wrapped by Expr which also holds onto contextual
|
||||
@ -185,41 +190,6 @@ func (tup Tuple) LLVMVal(builder llvm.Builder) llvm.Value {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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
|
||||
// previous expression
|
||||
//
|
||||
// TODO remove this, sorry Pipe
|
||||
type Pipe []Expr
|
||||
|
||||
func (p Pipe) String() string {
|
||||
strs := make([]string, len(p))
|
||||
for i := range p {
|
||||
strs[i] = fmt.Sprint(p[i].Actual)
|
||||
}
|
||||
return "(" + strings.Join(strs, "|") + ")"
|
||||
}
|
||||
|
||||
// Equal implements the Actual method
|
||||
func (p Pipe) Equal(e Actual) bool {
|
||||
pp, ok := e.(Pipe)
|
||||
if !ok || len(pp) != len(p) {
|
||||
return false
|
||||
}
|
||||
for i := range p {
|
||||
if !p[i].Actual.Equal(pp[i].Actual) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p Pipe) LLVMVal(builder llvm.Builder) llvm.Value {
|
||||
return llvm.Value{}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Statement represents an actual action which will be taken. The input value is
|
||||
// used as the input to the pipe, and the output of the pipe is the output of
|
||||
// the statement
|
||||
@ -396,7 +366,6 @@ var (
|
||||
openCurly = lexer.Token{TokenType: lexer.Wrapper, Val: "{"}
|
||||
closeCurly = lexer.Token{TokenType: lexer.Wrapper, Val: "}"}
|
||||
comma = lexer.Token{TokenType: lexer.Punctuation, Val: ","}
|
||||
pipe = lexer.Token{TokenType: lexer.Punctuation, Val: "|"}
|
||||
arrow = lexer.Token{TokenType: lexer.Punctuation, Val: ">"}
|
||||
)
|
||||
|
||||
@ -518,20 +487,12 @@ func parseConnectingPunct(toks []lexer.Token, root Expr) (Expr, []lexer.Token, e
|
||||
if toks[0].Equal(comma) {
|
||||
return parseTuple(toks, root)
|
||||
|
||||
} else if toks[0].Equal(pipe) {
|
||||
return parsePipe(toks, root)
|
||||
|
||||
} else if toks[0].Equal(arrow) {
|
||||
expr, toks, err := parse(toks[1:])
|
||||
if err != nil {
|
||||
return Expr{}, nil, err
|
||||
}
|
||||
pipe, ok := expr.Actual.(Pipe)
|
||||
if !ok {
|
||||
pipe = Pipe{expr}
|
||||
}
|
||||
pipeExpr := Expr{Actual: pipe, Token: expr.Token}
|
||||
return Expr{Token: root.Token, Actual: Statement{In: root, To: pipeExpr}}, toks, nil
|
||||
return Expr{Token: root.Token, Actual: Statement{In: root, To: expr}}, toks, nil
|
||||
}
|
||||
|
||||
return root, toks, nil
|
||||
@ -568,37 +529,6 @@ func parseTuple(toks []lexer.Token, root Expr) (Expr, []lexer.Token, error) {
|
||||
return parseTuple(toks, mkRoot())
|
||||
}
|
||||
|
||||
func parsePipe(toks []lexer.Token, root Expr) (Expr, []lexer.Token, error) {
|
||||
rootPipe, ok := root.Actual.(Pipe)
|
||||
if !ok {
|
||||
rootPipe = Pipe{root}
|
||||
}
|
||||
|
||||
// rootPipe is modified throughout, be we need to make it into an Expr for
|
||||
// every return, which is annoying. so make a function to do it on the fly
|
||||
mkRoot := func() Expr {
|
||||
return Expr{Token: rootPipe[0].Token, Actual: rootPipe}
|
||||
}
|
||||
|
||||
if len(toks) < 2 {
|
||||
return mkRoot(), toks, nil
|
||||
} else if !toks[0].Equal(pipe) {
|
||||
if toks[0].TokenType == lexer.Punctuation {
|
||||
return parseConnectingPunct(toks, mkRoot())
|
||||
}
|
||||
return mkRoot(), toks, nil
|
||||
}
|
||||
|
||||
var expr Expr
|
||||
var err error
|
||||
if expr, toks, err = parseSingle(toks[1:]); err != nil {
|
||||
return Expr{}, nil, err
|
||||
}
|
||||
|
||||
rootPipe = append(rootPipe, expr)
|
||||
return parsePipe(toks, mkRoot())
|
||||
}
|
||||
|
||||
// parseBlock assumes that the given token list is the entire block, already
|
||||
// pulled from outer curly braces by sliceEnclosedToks, or determined to be the
|
||||
// entire block in some other way.
|
||||
|
@ -90,41 +90,9 @@ func TestParseTuple(t *T) {
|
||||
assertParse(t, toks, tup(fooExpr, tup(fooExpr, fooExpr), fooExpr), []lexer.Token{foo})
|
||||
}
|
||||
|
||||
// This is basically the same as tuple
|
||||
func TestParsePipe(t *T) {
|
||||
mkPipe := func(ee ...Expr) Expr {
|
||||
return Expr{Actual: Pipe(ee)}
|
||||
}
|
||||
|
||||
foo := lexer.Token{TokenType: lexer.Identifier, Val: "foo"}
|
||||
fooExpr := Expr{Actual: Identifier("foo")}
|
||||
|
||||
toks := []lexer.Token{foo, pipe, foo}
|
||||
assertParse(t, toks, mkPipe(fooExpr, fooExpr), []lexer.Token{})
|
||||
|
||||
toks = []lexer.Token{foo, pipe, foo, foo}
|
||||
assertParse(t, toks, mkPipe(fooExpr, fooExpr), []lexer.Token{foo})
|
||||
|
||||
toks = []lexer.Token{foo, pipe, foo, pipe, foo}
|
||||
assertParse(t, toks, mkPipe(fooExpr, fooExpr, fooExpr), []lexer.Token{})
|
||||
|
||||
toks = []lexer.Token{foo, pipe, foo, pipe, foo, pipe, foo}
|
||||
assertParse(t, toks, mkPipe(fooExpr, fooExpr, fooExpr, fooExpr), []lexer.Token{})
|
||||
|
||||
toks = []lexer.Token{foo, pipe, openParen, foo, pipe, foo, closeParen, pipe, foo}
|
||||
assertParse(t, toks, mkPipe(fooExpr, mkPipe(fooExpr, fooExpr), fooExpr), []lexer.Token{})
|
||||
|
||||
toks = []lexer.Token{foo, pipe, openParen, foo, pipe, foo, closeParen, pipe, foo, foo}
|
||||
assertParse(t, toks, mkPipe(fooExpr, mkPipe(fooExpr, fooExpr), fooExpr), []lexer.Token{foo})
|
||||
|
||||
fooTupExpr := Expr{Actual: Tuple{fooExpr, fooExpr}}
|
||||
toks = []lexer.Token{foo, comma, foo, pipe, foo}
|
||||
assertParse(t, toks, mkPipe(fooTupExpr, fooExpr), []lexer.Token{})
|
||||
}
|
||||
|
||||
func TestParseStatement(t *T) {
|
||||
stmt := func(in Expr, ee ...Expr) Expr {
|
||||
return Expr{Actual: Statement{in: in, pipe: Pipe(ee)}}
|
||||
stmt := func(in, to Expr) Expr {
|
||||
return Expr{Actual: Statement{In: in, To: to}}
|
||||
}
|
||||
|
||||
foo := lexer.Token{TokenType: lexer.Identifier, Val: "foo"}
|
||||
@ -139,24 +107,21 @@ func TestParseStatement(t *T) {
|
||||
toks = []lexer.Token{foo, arrow, openParen, foo, closeParen}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr), []lexer.Token{})
|
||||
|
||||
toks = []lexer.Token{foo, arrow, foo, pipe, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr, fooExpr), []lexer.Token{})
|
||||
toks = []lexer.Token{foo, arrow, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr), []lexer.Token{})
|
||||
|
||||
toks = []lexer.Token{foo, arrow, foo, pipe, foo, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr, fooExpr), []lexer.Token{foo})
|
||||
toks = []lexer.Token{foo, arrow, foo, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr), []lexer.Token{foo})
|
||||
|
||||
toks = []lexer.Token{foo, arrow, openParen, foo, pipe, foo, closeParen, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr, fooExpr), []lexer.Token{foo})
|
||||
toks = []lexer.Token{foo, arrow, openParen, foo, closeParen, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr), []lexer.Token{foo})
|
||||
|
||||
toks = []lexer.Token{openParen, foo, closeParen, arrow, openParen, foo, pipe, foo, closeParen, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr, fooExpr), []lexer.Token{foo})
|
||||
|
||||
toks = []lexer.Token{openParen, foo, closeParen, arrow, openParen, foo, pipe, foo, closeParen, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr, fooExpr), []lexer.Token{foo})
|
||||
toks = []lexer.Token{openParen, foo, closeParen, arrow, openParen, foo, closeParen, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooExpr), []lexer.Token{foo})
|
||||
|
||||
fooTupExpr := Expr{Actual: Tuple{fooExpr, fooExpr}}
|
||||
toks = []lexer.Token{foo, arrow, openParen, foo, comma, foo, closeParen, pipe, foo, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooTupExpr, fooExpr), []lexer.Token{foo})
|
||||
toks = []lexer.Token{foo, arrow, openParen, foo, comma, foo, closeParen, foo}
|
||||
assertParse(t, toks, stmt(fooExpr, fooTupExpr), []lexer.Token{foo})
|
||||
|
||||
toks = []lexer.Token{foo, comma, foo, arrow, foo}
|
||||
assertParse(t, toks, stmt(fooTupExpr, fooExpr), []lexer.Token{})
|
||||
@ -166,8 +131,8 @@ func TestParseStatement(t *T) {
|
||||
}
|
||||
|
||||
func TestParseBlock(t *T) {
|
||||
stmt := func(in Expr, ee ...Expr) Statement {
|
||||
return Statement{in: in, pipe: Pipe(ee)}
|
||||
stmt := func(in, to Expr) Statement {
|
||||
return Statement{In: in, To: to}
|
||||
}
|
||||
block := func(stmts ...Statement) Expr {
|
||||
return Expr{Actual: Block(stmts)}
|
||||
|
@ -198,7 +198,7 @@ func (l *Lexer) Next() Token {
|
||||
// the actual fsm
|
||||
|
||||
var whitespaceSet = " \n\r\t\v\f"
|
||||
var punctuationSet = ",<>|"
|
||||
var punctuationSet = ",>"
|
||||
var wrapperSet = "{}()"
|
||||
var identifierSepSet = whitespaceSet + punctuationSet + wrapperSet
|
||||
|
||||
|
@ -32,7 +32,7 @@ var lexTestSrc = `
|
||||
*/
|
||||
*/
|
||||
|
||||
(punctuation,is{cool}<> )
|
||||
(punctuation,is{cool}> )
|
||||
-tab
|
||||
|
||||
"this is a string", "and so is this one"
|
||||
@ -67,9 +67,8 @@ func TestLex(t *T) {
|
||||
assertNext(Wrapper, "{", 24, 17)
|
||||
assertNext(Identifier, "cool", 24, 18)
|
||||
assertNext(Wrapper, "}", 24, 22)
|
||||
assertNext(Punctuation, "<", 24, 23)
|
||||
assertNext(Punctuation, ">", 24, 24)
|
||||
assertNext(Wrapper, ")", 24, 26)
|
||||
assertNext(Punctuation, ">", 24, 23)
|
||||
assertNext(Wrapper, ")", 24, 25)
|
||||
assertNext(Identifier, "-tab", 25, 2)
|
||||
assertNext(String, `"this is a string"`, 27, 2)
|
||||
assertNext(Punctuation, ",", 27, 20)
|
||||
|
Loading…
Reference in New Issue
Block a user