package shsh

import (
    "strings"
    "fmt"
)

func FmtToken(arg *Token) string {
    suffix := "->"
    if arg.next == nil {
        suffix = ""
    }

    switch arg.tag {
    case LIST:
        return fmt.Sprintf("(%s, List @ %p, %d)%s", "LIST", arg._inner,
            arg.position, suffix)

    default:
        return fmt.Sprintf("(%s, %s, %d)%s", GetTagAsStr(arg.tag), arg._inner,
            arg.position, suffix)
    }
}

func GetTagAsStr(tag token_t) string {
    switch tag {
    case LIST:
        return "LIST"
    case STRING:
        return "STRING"
    case NUMBER:
        return "NUMBER"
    case SYMBOL:
        return "SYMBOL"
    }
    return "UNKNOWN"
}

func PrintSExpression(arg *Token) {
    if arg == nil {
        return //TODO: Handle error here?
    }

    var lists TokenStack;
    lists.Push(arg)

loop:
    var constructor strings.Builder
    i := lists.Pop()
    if i == nil {
        return
    }

    for iter := i; iter != nil; iter = iter.next {
        if iter.tag == LIST {
            lists.Push(iter._inner.(*Token))
            constructor.WriteString(FmtToken(&Token{
                next: iter.next,
                tag: STRING,
                position: iter.position,
                _inner: "[LIST]"}))
            continue
        }

        constructor.WriteString(FmtToken(iter))
    }

    println(constructor.String())
    goto loop
}
