Ejemplo n.º 1
0
Archivo: env.go Proyecto: suzuken/gigue
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
}
Ejemplo n.º 2
0
// 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
	}
}
Ejemplo n.º 3
0
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)
	}
}
Ejemplo n.º 4
0
Archivo: env.go Proyecto: suzuken/gigue
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
}
Ejemplo n.º 5
0
Archivo: env.go Proyecto: suzuken/gigue
func IsString(args ...types.Expression) (types.Expression, error) {
	if _, ok := args[0].(string); !ok {
		return types.Boolean(false), nil
	}
	return types.Boolean(true), nil
}
Ejemplo n.º 6
0
Archivo: env.go Proyecto: suzuken/gigue
func IsEqual(args ...types.Expression) (types.Expression, error) {
	return types.Boolean(args[0] == args[1]), nil
}
Ejemplo n.º 7
0
Archivo: env.go Proyecto: suzuken/gigue
func LessThanEqual(args ...types.Expression) (types.Expression, error) {
	return types.Boolean(args[0].(types.Number) <= args[1].(types.Number)), nil
}
Ejemplo n.º 8
0
Archivo: env.go Proyecto: suzuken/gigue
func GreaterThan(args ...types.Expression) (types.Expression, error) {
	return types.Boolean(args[0].(types.Number) > args[1].(types.Number)), nil
}