eval: add len
This commit is contained in:
@@ -9,9 +9,8 @@
|
||||
- Destructuring assignment
|
||||
- `maptable`
|
||||
- `coerce`
|
||||
- `len`
|
||||
- `mac`
|
||||
- `\``
|
||||
- `````
|
||||
- `w/link`
|
||||
- `aform`
|
||||
- ...
|
||||
|
14
ast/ast.go
14
ast/ast.go
@@ -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
|
||||
}
|
||||
|
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