lang: Add some lambda function parsing and tests
Part of this isn't fully implemented, but might as well get the tests running.
This commit is contained in:
@@ -1769,6 +1769,140 @@ func TestLexParse0(t *testing.T) {
|
||||
exp: exp,
|
||||
})
|
||||
}
|
||||
{
|
||||
|
||||
fn := &ExprFunc{
|
||||
Body: &ExprInt{
|
||||
V: 42,
|
||||
},
|
||||
}
|
||||
exp := &StmtProg{
|
||||
Prog: []interfaces.Stmt{
|
||||
&StmtBind{
|
||||
Ident: "fn",
|
||||
Value: fn,
|
||||
},
|
||||
},
|
||||
}
|
||||
testCases = append(testCases, test{
|
||||
name: "simple function expr 1",
|
||||
code: `
|
||||
# lambda
|
||||
$fn = func() {
|
||||
42
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
exp: exp,
|
||||
})
|
||||
}
|
||||
{
|
||||
fn := &ExprFunc{
|
||||
Args: []*Arg{
|
||||
{
|
||||
Name: "x",
|
||||
Type: types.TypeStr,
|
||||
},
|
||||
},
|
||||
Return: types.TypeStr,
|
||||
Body: &ExprCall{
|
||||
Name: operatorFuncName,
|
||||
Args: []interfaces.Expr{
|
||||
&ExprStr{
|
||||
V: "+",
|
||||
},
|
||||
&ExprStr{
|
||||
V: "hello",
|
||||
},
|
||||
&ExprVar{
|
||||
Name: "x",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := fn.SetType(types.NewType("func(x str) str")); err != nil {
|
||||
t.Fatal("could not build type")
|
||||
}
|
||||
exp := &StmtProg{
|
||||
Prog: []interfaces.Stmt{
|
||||
&StmtBind{
|
||||
Ident: "fn",
|
||||
Value: fn,
|
||||
},
|
||||
},
|
||||
}
|
||||
testCases = append(testCases, test{
|
||||
name: "simple function expr 2",
|
||||
code: `
|
||||
# lambda
|
||||
$fn = func($x str) str {
|
||||
"hello" + $x
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
exp: exp,
|
||||
})
|
||||
}
|
||||
{
|
||||
fn := &ExprFunc{
|
||||
Args: []*Arg{
|
||||
{
|
||||
Name: "x",
|
||||
Type: types.TypeStr,
|
||||
},
|
||||
},
|
||||
Return: types.TypeStr,
|
||||
Body: &ExprCall{
|
||||
Name: operatorFuncName,
|
||||
Args: []interfaces.Expr{
|
||||
&ExprStr{
|
||||
V: "+",
|
||||
},
|
||||
&ExprStr{
|
||||
V: "hello",
|
||||
},
|
||||
&ExprVar{
|
||||
Name: "x",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := fn.SetType(types.NewType("func(x str) str")); err != nil {
|
||||
t.Fatal("could not build type")
|
||||
}
|
||||
exp := &StmtProg{
|
||||
Prog: []interfaces.Stmt{
|
||||
&StmtBind{
|
||||
Ident: "fn",
|
||||
Value: fn,
|
||||
},
|
||||
&StmtBind{
|
||||
Ident: "foo",
|
||||
Value: &ExprCall{
|
||||
Name: "fn",
|
||||
Args: []interfaces.Expr{
|
||||
&ExprStr{
|
||||
V: "world",
|
||||
},
|
||||
},
|
||||
//Var: true, // XXX: add this!
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
testCases = append(testCases, test{
|
||||
name: "simple function expr 3",
|
||||
code: `
|
||||
# lambda
|
||||
$fn = func($x str) str {
|
||||
"hello" + $x
|
||||
}
|
||||
$foo = $fn("world") # helloworld
|
||||
`,
|
||||
fail: false,
|
||||
exp: exp,
|
||||
})
|
||||
}
|
||||
|
||||
names := []string{}
|
||||
for index, tc := range testCases { // run all the tests
|
||||
|
||||
@@ -496,12 +496,26 @@ struct_field:
|
||||
}
|
||||
;
|
||||
call:
|
||||
// fmt.printf(...)
|
||||
dotted_identifier OPEN_PAREN call_args CLOSE_PAREN
|
||||
{
|
||||
posLast(yylex, yyDollar) // our pos
|
||||
$$.expr = &ExprCall{
|
||||
Name: $1.str,
|
||||
Args: $3.exprs,
|
||||
//Var: false, // default
|
||||
}
|
||||
}
|
||||
// calling a function that's stored in a variable (a lambda)
|
||||
// `$foo(4, "hey")` # call function value
|
||||
| VAR_IDENTIFIER OPEN_PAREN call_args CLOSE_PAREN
|
||||
{
|
||||
posLast(yylex, yyDollar) // our pos
|
||||
$$.expr = &ExprCall{
|
||||
Name: $1.str,
|
||||
Args: $3.exprs,
|
||||
// XXX: this Var option isn't implemented yet
|
||||
//Var: true, // lambda
|
||||
}
|
||||
}
|
||||
| expr PLUS expr
|
||||
|
||||
Reference in New Issue
Block a user