func IsList(args ...types.Expression) (types.Expression, error) { pair, ok := args[0].(*types.Pair) if !ok { return types.Boolean(false), nil } return types.Boolean(pair.IsList()), nil }
// Parse scans given tokens and return it into expression. func (p *Parser) Parse() (exps types.Expression, err error) { token, err := p.lex.Next() if err != nil { return nil, err } switch token { case "'": // if start with (, deal as list. // recursive scan until ")" // if start with "'(", it's list. if p.lex.Peek() == '(' { // this is (. skip it. if _, err := p.lex.Next(); err != nil { return nil, err } tokens, err := p.parseList() if err != nil { return nil, err } return types.NewList(tokens...), nil } // if not start with (, it's simply string (return string itself). t, err := p.lex.Next() if err != nil { return nil, err } return types.Symbol(t), nil case "(": // start S-Expression. Parse as list. return p.parseList() case ")": return nil, errors.New("unexpected ')'") case "#t": return types.Boolean(true), nil case "#f": return types.Boolean(false), nil default: // if token is string, get unquoted. // It's get test from \"test\". if p.lex.IsTokenString() { return strconv.Unquote(p.lex.TokenText()) } // try conversion to float. if failed, treated as symbol. if n, err := strconv.ParseFloat(token, 64); err == nil { return types.Number(n), nil } return types.Symbol(token), nil } }
func TestParseBoolean(t *testing.T) { r := strings.NewReader("(print #t)") parser := New(lexer.New(r)) actual := []types.Expression{ types.Symbol("print"), types.Boolean(true), } exps, err := parser.Parse() if err != nil { t.Fatalf("parser failed: %s", err) } if !reflect.DeepEqual(exps, actual) { t.Fatalf("expressions is not expected. %#v", exps) } }
func IsSymbol(args ...types.Expression) (types.Expression, error) { if _, ok := args[0].(types.Symbol); !ok { return types.Boolean(false), nil } return types.Boolean(true), nil }
func IsString(args ...types.Expression) (types.Expression, error) { if _, ok := args[0].(string); !ok { return types.Boolean(false), nil } return types.Boolean(true), nil }
func IsEqual(args ...types.Expression) (types.Expression, error) { return types.Boolean(args[0] == args[1]), nil }
func LessThanEqual(args ...types.Expression) (types.Expression, error) { return types.Boolean(args[0].(types.Number) <= args[1].(types.Number)), nil }
func GreaterThan(args ...types.Expression) (types.Expression, error) { return types.Boolean(args[0].(types.Number) > args[1].(types.Number)), nil }