func parseToken(t *tokenizer) (types.Type, bool, error) { var token string var err error if token, err = t.nextToken(); err != nil { return nil, false, err } if isQuote(token) { cadr, _, err := parseToken(t) if err != nil { return nil, false, err } return types.Cons(&types.Symbol{"quote"}, types.Cons(cadr, nil)), false, nil } if isListEnd(token) { return nil, true, nil } if isList(token) { r, err := list(t) return r, false, err } if isSymbol(token) { return &types.Symbol{token}, false, nil } if isString(token) { s, err := makeString(token) if err != nil { return nil, false, err } return s, false, nil } if isNum(token) { n, err := strconv.ParseInt(token, 10, 64) if err != nil { return nil, false, err } return &types.Number{n}, false, nil } switch token { case "#t": return &types.Bool{true}, false, nil case "#f": return &types.Bool{false}, false, nil } return nil, false, &parseError{"Unknown type", token} }
func evalArgs(env *environment.Environment, args types.Type) (types.Type, error) { if args == nil { return nil, nil } arg, err := types.Car(args) if err != nil { return nil, err } car, err := Eval(env, arg) if err != nil { return nil, err } next, err := types.Cdr(args) if err != nil { return nil, err } cdr, err := evalArgs(env, next) if err != nil { return nil, err } return types.Cons(car, cdr), nil }
func cons(env interface{}, args t.Type) (t.Type, error) { a, err := car(nil, args) if err != nil { return nil, err } b, err := cdr(nil, args) if err != nil { return nil, err } return t.Cons(a, b), nil }
func list(t *tokenizer) (types.Type, error) { car, listEnd, err := parseToken(t) if err != nil { return nil, err } if listEnd { return nil, nil } cdr, err := list(t) if err != nil { return nil, err } return types.Cons(car, cdr), nil }
func Define(env *Environment, sym *types.Symbol, item types.Type) { env.env = types.Cons(types.Cons(sym, item), env.env) }