package main

import (
	"fmt"
	"strconv"
)

type (
	_unknown struct {
		s string
	}

	_number struct {
		num  float64
		word string
	}

	_bool struct {
		b    bool
		word string
	}

	_word struct {
		word string
	}

	_list struct {
		list  []string
		param []string
		body  []string
		env   environ
	}

	value interface {
		fmt.Stringer
	}

	environ map[string]value
)

func (val *_unknown) String() string {
	return val.s
}

func (val *_number) String() string {
	if len(val.word) > 0 {
		return val.word
	}
	return strconv.FormatFloat(val.num, 'g', -1, 64)
}

func (val *_number) Value() float64 {
	return val.num
}

func (val *_bool) String() string {
	if len(val.word) > 0 {
		return val.word
	}
	return strconv.FormatBool(val.b)
}

func (val *_bool) Value() bool {
	return val.b
}

func (val *_word) String() string {
	return val.word
}

func (val *_word) Value() string {
	return val.word
}

func (val *_list) String() string {
	return makeList(val.list)
}

func (val *_list) Value() []string {
	return val.list
}
