// +build !gui,!all package main import ( "fmt" "strconv" "strings" ) var guiLib = vars{} func String(v expression, rawString bool) string { switch v := v.(type) { case []expression: l := make([]string, len(v)) for i, x := range v { l[i] = String(x, true) } return "(" + strings.Join(l, " ") + ")" case string: if rawString { return fmt.Sprintf("\"%s\"", escapeString(v)) } return v case exception: return string(v) case bool: if v { return "#t" } return "#f" case number: return strconv.FormatFloat(float64(v), 'f', -1, 64) case proc: var b strings.Builder b.WriteString("(lambda ") params, ok := v.params.([]expression) if len(v.predicates) > 0 { if ok { newParams := make([]expression, len(params)) copy(newParams, params) for i := range newParams { if pred, ok := v.predicates[newParams[i].(symbol)]; ok { newParams[i] = symbol(fmt.Sprintf("%s@%s", newParams[i].(symbol), pred)) } } b.WriteString(String(newParams, true)) } else { val := String(v.params, false) b.WriteString(val) b.WriteString("@") b.WriteString(string(v.predicates[symbol(val)])) } } else { b.WriteString(String(v.params, true)) } b.WriteRune(' ') body := String(v.body, true) if strings.HasPrefix(body, "(begin ") { body = body[7:] } b.WriteString(body) return b.String() case macro: var b strings.Builder b.WriteString("(macro ") b.WriteString(String(v.params, true)) b.WriteRune(' ') body := String(v.body, true) if strings.HasPrefix(body, "(begin ") { body = body[7:] } b.WriteString(body) return b.String() case func(...expression) expression: return fmt.Sprint("Built-in: ", &v) case *IOHandle: return fmt.Sprintf("%+v", v) default: return fmt.Sprint(v) } }