eval: add maptable
This commit is contained in:
45
eval/eval.go
45
eval/eval.go
@@ -481,6 +481,49 @@ func evalLen(l []*ast.AST) (*ast.AST, error) {
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func evalMapTable(l []*ast.AST, e ast.Env) (*ast.AST, error) {
|
||||
err := checkArity(l, 2, "maptable")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, err := Eval(l[0], e)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maybeLst, err := Eval(l[1], e)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if maybeLst.Tag != ast.Table {
|
||||
return nil, fmt.Errorf("Second argument to maptable must be table")
|
||||
}
|
||||
|
||||
lst := maybeLst.Val.(map[*ast.AST]*ast.AST)
|
||||
|
||||
var res []*ast.AST
|
||||
|
||||
for k, v := range lst {
|
||||
toEval := ast.AST{ast.List, []*ast.AST{f, k, v}}
|
||||
evald, err := Eval(&toEval, e)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = append(res, evald)
|
||||
}
|
||||
|
||||
reslst := ast.AST{ast.List, res}
|
||||
quoted := ast.AST{ast.Quoted, &reslst}
|
||||
return "ed, nil
|
||||
}
|
||||
|
||||
func evalSymbolList(l []*ast.AST, e ast.Env) (*ast.AST, error) {
|
||||
sym := l[0].Val.(string)
|
||||
|
||||
@@ -519,6 +562,8 @@ func evalSymbolList(l []*ast.AST, e ast.Env) (*ast.AST, error) {
|
||||
return evalLog(l, e, func(x float64, y float64) bool { return x < y })
|
||||
case ">":
|
||||
return evalLog(l, e, func(x float64, y float64) bool { return x > y })
|
||||
case "maptable":
|
||||
return evalMapTable(l, e)
|
||||
}
|
||||
res, err := e.Lookup(sym)
|
||||
|
||||
|
Reference in New Issue
Block a user