eval: add len
This commit is contained in:
30
eval/eval.go
30
eval/eval.go
@@ -26,6 +26,7 @@ func RootEnv() ast.Env {
|
||||
"pr": evalPr,
|
||||
"table": evalTable,
|
||||
"type": evalType,
|
||||
"len": evalLen,
|
||||
}
|
||||
|
||||
for k, v := range prims {
|
||||
@@ -302,7 +303,7 @@ func evalFn(input []*ast.AST, e ast.Env) (*ast.AST, error) {
|
||||
|
||||
body := input[1]
|
||||
|
||||
fe := ast.NewEnv(&e)
|
||||
fe := ast.NewEnv(&e)
|
||||
|
||||
res := ast.AST{ast.Fn, ast.Func{argsStr, rest, opt, body, fe}}
|
||||
return &res, nil
|
||||
@@ -453,6 +454,33 @@ func evalType(l []*ast.AST) (*ast.AST, error) {
|
||||
return l[0].Type(), nil
|
||||
}
|
||||
|
||||
func evalLen(l []*ast.AST) (*ast.AST, error) {
|
||||
err := checkArity(l, 1, "len")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cnt := 0
|
||||
elem := l[0]
|
||||
|
||||
switch elem.Tag {
|
||||
case ast.Quoted:
|
||||
// TODO: error handling
|
||||
cnt = len(elem.Val.(*ast.AST).Val.([]*ast.AST))
|
||||
case ast.String:
|
||||
cnt = len(elem.Val.(string))
|
||||
case ast.Table:
|
||||
cnt = len(elem.Val.(map[*ast.AST]*ast.AST))
|
||||
default:
|
||||
return nil, fmt.Errorf("Cannot get length of %s", elem.Pretty())
|
||||
}
|
||||
|
||||
res := ast.AST{ast.Num, float64(cnt)}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func evalSymbolList(l []*ast.AST, e ast.Env) (*ast.AST, error) {
|
||||
sym := l[0].Val.(string)
|
||||
|
||||
|
Reference in New Issue
Block a user