eval: add len

This commit is contained in:
2018-05-14 22:03:46 +02:00
parent 4be6927dc2
commit f114369c65
3 changed files with 37 additions and 10 deletions

View File

@@ -9,9 +9,8 @@
- Destructuring assignment
- `maptable`
- `coerce`
- `len`
- `mac`
- `\``
- `````
- `w/link`
- `aform`
- ...

View File

@@ -94,14 +94,14 @@ func (ast *AST) Pretty() string {
rest = " . " + *val.Rest
}
// TODO: opt
opt := ""
opt := ""
iter := val.Opt.IterFunc()
for kv, ok := iter(); ok; kv, ok = iter() {
opt += "(o " + kv.Key.(string) + " " + kv.Value.(*AST).Pretty() + ")"
}
if val.HasOpt() && (val.HasRest() || len(agg) != 0) {
opt = " " + opt
}
opt += "(o " + kv.Key.(string) + " " + kv.Value.(*AST).Pretty() + ")"
}
if val.HasOpt() && (val.HasRest() || len(agg) != 0) {
opt = " " + opt
}
body := val.Body.Pretty()
return "(fn (" + strings.Join(agg, " ") + rest + opt + ") " + body + ")"
} else if ast.Tag == Char {
@@ -167,5 +167,5 @@ func (f *Func) HasRest() bool {
}
func (f *Func) HasOpt() bool {
return f.Opt.Len() != 0
return f.Opt.Len() != 0
}

View File

@@ -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)