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,
|
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{}
|
names := []string{}
|
||||||
for index, tc := range testCases { // run all the tests
|
for index, tc := range testCases { // run all the tests
|
||||||
|
|||||||
@@ -496,12 +496,26 @@ struct_field:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
call:
|
call:
|
||||||
|
// fmt.printf(...)
|
||||||
dotted_identifier OPEN_PAREN call_args CLOSE_PAREN
|
dotted_identifier OPEN_PAREN call_args CLOSE_PAREN
|
||||||
{
|
{
|
||||||
posLast(yylex, yyDollar) // our pos
|
posLast(yylex, yyDollar) // our pos
|
||||||
$$.expr = &ExprCall{
|
$$.expr = &ExprCall{
|
||||||
Name: $1.str,
|
Name: $1.str,
|
||||||
Args: $3.exprs,
|
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
|
| expr PLUS expr
|
||||||
|
|||||||
Reference in New Issue
Block a user