|
1 | 1 | package main
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "errors" |
4 | 5 | "fmt"
|
5 | 6 | "io"
|
6 | 7 | "os"
|
|
57 | 58 | "quit": ExprFunc(stdQuit),
|
58 | 59 | "exit": ExprFunc(stdQuit),
|
59 | 60 | "time-ms": ExprFunc(stdTimeMs),
|
| 61 | + "bool": ExprFunc(stdBool), |
| 62 | + "seq": ExprFunc(stdSeq), |
| 63 | + "conj": ExprFunc(stdConj), |
60 | 64 | }}
|
61 | 65 | )
|
62 | 66 |
|
@@ -205,12 +209,22 @@ func stdIs(args []Expr) (Expr, error) {
|
205 | 209 | if _, ok = args[1].(*ExprFn); !ok {
|
206 | 210 | _, ok = args[1].(ExprFunc)
|
207 | 211 | }
|
| 212 | + case ":macro": |
| 213 | + if fn, _ := args[1].(*ExprFn); fn != nil { |
| 214 | + ok = fn.isMacro |
| 215 | + } |
208 | 216 | case ":err":
|
209 | 217 | _, ok = args[1].(ExprErr)
|
210 | 218 | case ":atom":
|
211 | 219 | _, ok = args[1].(*ExprAtom)
|
| 220 | + case ":nil": |
| 221 | + ok = (isEq(exprNil, args[1])) |
| 222 | + case ":true": |
| 223 | + ok = (isEq(exprTrue, args[1])) |
| 224 | + case ":false": |
| 225 | + ok = (isEq(exprFalse, args[1])) |
212 | 226 | default:
|
213 |
| - return nil, fmt.Errorf("expected not `%s` but one of: `:list`, `:ident`, `:str`, `:num`, `:vec`, `:hashmap`, `:fn`, `:keyword`, `:atom`, `:err`", kind) |
| 227 | + return nil, fmt.Errorf("expected not `%s` but one of: `:list`, `:ident`, `:str`, `:num`, `:vec`, `:hashmap`, `:fn`, `:macro`, `:keyword`, `:atom`, `:err`, `:nil`, `:true`, `:false`", kind) |
214 | 228 | }
|
215 | 229 | return exprBool(ok), nil
|
216 | 230 | }
|
@@ -662,3 +676,46 @@ func stdQuit(args []Expr) (Expr, error) {
|
662 | 676 | func stdTimeMs(args []Expr) (Expr, error) {
|
663 | 677 | return ExprNum(time.Now().UnixMilli()), nil
|
664 | 678 | }
|
| 679 | + |
| 680 | +func stdBool(args []Expr) (Expr, error) { |
| 681 | + if err := checkArgsCount(1, 1, args); err != nil { |
| 682 | + return nil, err |
| 683 | + } |
| 684 | + return exprBool((!isEq(exprFalse, args[0])) && !isEq(exprNil, args[0])), nil |
| 685 | +} |
| 686 | + |
| 687 | +func stdSeq(args []Expr) (Expr, error) { |
| 688 | + if err := checkArgsCount(1, 1, args); err != nil { |
| 689 | + return nil, err |
| 690 | + } |
| 691 | + if isEq(exprNil, args[0]) { |
| 692 | + return args[0], nil |
| 693 | + } |
| 694 | + switch it := args[0].(type) { |
| 695 | + case ExprList: |
| 696 | + if len(it) == 0 { |
| 697 | + return exprNil, nil |
| 698 | + } |
| 699 | + return it, nil |
| 700 | + case ExprVec: |
| 701 | + if len(it) == 0 { |
| 702 | + return exprNil, nil |
| 703 | + } |
| 704 | + return (ExprList)(it), nil |
| 705 | + case ExprStr: |
| 706 | + if len(it) == 0 { |
| 707 | + return exprNil, nil |
| 708 | + } |
| 709 | + expr := make(ExprList, 0, len(it)) |
| 710 | + for _, char := range it { |
| 711 | + expr = append(expr, ExprStr(char)) |
| 712 | + } |
| 713 | + return expr, nil |
| 714 | + } |
| 715 | + |
| 716 | + return nil, fmt.Errorf("expected a list, vector, string or :nil instead of `%s`", str(true, args[0])) |
| 717 | +} |
| 718 | + |
| 719 | +func stdConj(args []Expr) (Expr, error) { |
| 720 | + return nil, errors.New("TODO") |
| 721 | +} |
0 commit comments