From a3a84dcb983597f2888fbf4637cae9d8873f914c Mon Sep 17 00:00:00 2001 From: hellerve Date: Mon, 14 May 2018 22:17:12 +0200 Subject: [PATCH] eval: add maptable --- README.md | 1 - eval/eval.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 516680b..c87afbb 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ ## TODOS - Destructuring assignment -- `maptable` - `coerce` - `mac` - ````` diff --git a/eval/eval.go b/eval/eval.go index d9ef2e0..8c925ea 100644 --- a/eval/eval.go +++ b/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)