123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- package glisp
- import (
- "reflect"
- "strconv"
- "strings"
- )
- type Sexp interface {
- SexpString() string
- }
- type SexpSentinel int
- const (
- SexpNull SexpSentinel = iota
- SexpEnd
- SexpMarker
- )
- func (sent SexpSentinel) SexpString() string {
- if sent == SexpNull {
- return "()"
- }
- if sent == SexpEnd {
- return "End"
- }
- if sent == SexpMarker {
- return "Marker"
- }
- return ""
- }
- type SexpPair struct {
- head Sexp
- tail Sexp
- }
- func Cons(a Sexp, b Sexp) SexpPair {
- return SexpPair{a, b}
- }
- func (pair SexpPair) Head() Sexp {
- return pair.head
- }
- func (pair SexpPair) Tail() Sexp {
- return pair.tail
- }
- func (pair SexpPair) SexpString() string {
- str := "("
- for {
- switch pair.tail.(type) {
- case SexpPair:
- str += pair.head.SexpString() + " "
- pair = pair.tail.(SexpPair)
- continue
- }
- break
- }
- str += pair.head.SexpString()
- if pair.tail == SexpNull {
- str += ")"
- } else {
- str += " . " + pair.tail.SexpString() + ")"
- }
- return str
- }
- type SexpArray []Sexp
- type SexpHash struct {
- TypeName *string
- Map map[int][]SexpPair
- KeyOrder *[]Sexp // must user pointers here, else hset! will fail to update.
- GoStruct *interface{}
- NumKeys *int
- }
- type SexpInt int
- type SexpBool bool
- type SexpFloat float64
- type SexpChar rune
- type SexpStr string
- var SexpIntSize = reflect.TypeOf(SexpInt(0)).Bits()
- var SexpFloatSize = reflect.TypeOf(SexpFloat(0.0)).Bits()
- func (arr SexpArray) SexpString() string {
- if len(arr) == 0 {
- return "[]"
- }
- str := "[" + arr[0].SexpString()
- for _, sexp := range arr[1:] {
- str += " " + sexp.SexpString()
- }
- str += "]"
- return str
- }
- func (hash SexpHash) SexpString() string {
- str := "{"
- for _, arr := range hash.Map {
- for _, pair := range arr {
- str += pair.head.SexpString() + " "
- str += pair.tail.SexpString() + " "
- }
- }
- if len(str) > 1 {
- return str[:len(str)-1] + "}"
- }
- return str + "}"
- }
- func (b SexpBool) SexpString() string {
- if b {
- return "true"
- }
- return "false"
- }
- func (i SexpInt) SexpString() string {
- return strconv.Itoa(int(i))
- }
- func (f SexpFloat) SexpString() string {
- return strconv.FormatFloat(float64(f), 'g', 5, SexpFloatSize)
- }
- func (c SexpChar) SexpString() string {
- return "#" + strings.Trim(strconv.QuoteRune(rune(c)), "'")
- }
- func (s SexpStr) SexpString() string {
- return strconv.Quote(string(s))
- }
- type SexpSymbol struct {
- name string
- number int
- }
- func (sym SexpSymbol) SexpString() string {
- return sym.name
- }
- func (sym SexpSymbol) Name() string {
- return sym.name
- }
- func (sym SexpSymbol) Number() int {
- return sym.number
- }
- type SexpFunction struct {
- name string
- user bool
- nargs int
- varargs bool
- fun GlispFunction
- userfun GlispUserFunction
- closeScope *Stack
- }
- func (sf SexpFunction) SexpString() string {
- return "fn [" + sf.name + "]"
- }
- func IsTruthy(expr Sexp) bool {
- switch e := expr.(type) {
- case SexpBool:
- return bool(e)
- case SexpInt:
- return e != 0
- case SexpChar:
- return e != 0
- case SexpSentinel:
- return e != SexpNull
- }
- return true
- }
- type SexpStackmark struct {
- sym SexpSymbol
- }
- func (mark SexpStackmark) SexpString() string {
- return "stackmark " + mark.sym.name
- }
|