mirror of
https://codeberg.org/scip/tablizer.git
synced 2025-12-19 13:31:02 +01:00
added
This commit is contained in:
694
vendor/github.com/glycerine/zygomys/zygo/expressions.go
generated
vendored
Normal file
694
vendor/github.com/glycerine/zygomys/zygo/expressions.go
generated
vendored
Normal file
@@ -0,0 +1,694 @@
|
||||
package zygo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// all Sexp are typed, and have a zero value corresponding to
|
||||
// the type of the Sexp.
|
||||
|
||||
// Sexp is the central interface for all
|
||||
// S-expressions (Symbol expressions ala lisp).
|
||||
type Sexp interface {
|
||||
// SexpString: produce a string from our value.
|
||||
// Single-line strings can ignore indent.
|
||||
// Only multiline strings should follow every
|
||||
// newline with at least indent worth of spaces.
|
||||
SexpString(ps *PrintState) string
|
||||
|
||||
// Type returns the type of the value.
|
||||
Type() *RegisteredType
|
||||
}
|
||||
|
||||
type SexpPair struct {
|
||||
Head Sexp
|
||||
Tail Sexp
|
||||
}
|
||||
|
||||
type SexpPointer struct {
|
||||
ReflectTarget reflect.Value
|
||||
Target Sexp
|
||||
PointedToType *RegisteredType
|
||||
MyType *RegisteredType
|
||||
}
|
||||
|
||||
func NewSexpPointer(pointedTo Sexp) *SexpPointer {
|
||||
pointedToType := pointedTo.Type()
|
||||
|
||||
var reftarg reflect.Value
|
||||
|
||||
Q("NewSexpPointer sees pointedTo of '%#v'", pointedTo)
|
||||
switch e := pointedTo.(type) {
|
||||
case *SexpReflect:
|
||||
Q("SexpReflect.Val = '%#v'", e.Val)
|
||||
reftarg = e.Val
|
||||
default:
|
||||
reftarg = reflect.ValueOf(pointedTo)
|
||||
}
|
||||
|
||||
ptrRt := GoStructRegistry.GetOrCreatePointerType(pointedToType)
|
||||
Q("pointer type is ptrRt = '%#v'", ptrRt)
|
||||
p := &SexpPointer{
|
||||
ReflectTarget: reftarg,
|
||||
Target: pointedTo,
|
||||
PointedToType: pointedToType,
|
||||
MyType: ptrRt,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *SexpPointer) SexpString(ps *PrintState) string {
|
||||
return fmt.Sprintf("%p", &p.Target)
|
||||
//return fmt.Sprintf("(* %v) %p", p.PointedToType.RegisteredName, p.Target)
|
||||
}
|
||||
|
||||
func (p *SexpPointer) Type() *RegisteredType {
|
||||
return p.MyType
|
||||
}
|
||||
|
||||
type SexpInt struct {
|
||||
Val int64
|
||||
Typ *RegisteredType
|
||||
}
|
||||
type SexpUint64 struct {
|
||||
Val uint64
|
||||
Typ *RegisteredType
|
||||
}
|
||||
type SexpBool struct {
|
||||
Val bool
|
||||
Typ *RegisteredType
|
||||
}
|
||||
type SexpFloat struct {
|
||||
Val float64
|
||||
Typ *RegisteredType
|
||||
Scientific bool
|
||||
}
|
||||
type SexpChar struct {
|
||||
Val rune
|
||||
Typ *RegisteredType
|
||||
}
|
||||
type SexpStr struct {
|
||||
S string
|
||||
backtick bool
|
||||
Typ *RegisteredType
|
||||
}
|
||||
|
||||
func (r SexpStr) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["string"]
|
||||
}
|
||||
|
||||
func (r *SexpInt) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["int64"]
|
||||
}
|
||||
|
||||
func (r *SexpUint64) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["uint64"]
|
||||
}
|
||||
|
||||
func (r *SexpFloat) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["float64"]
|
||||
}
|
||||
|
||||
func (r *SexpBool) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["bool"]
|
||||
}
|
||||
|
||||
func (r *SexpChar) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["int32"]
|
||||
}
|
||||
|
||||
func (r *RegisteredType) Type() *RegisteredType {
|
||||
return r
|
||||
}
|
||||
|
||||
type SexpRaw struct {
|
||||
Val []byte
|
||||
Typ *RegisteredType
|
||||
}
|
||||
|
||||
func (r *SexpRaw) Type() *RegisteredType {
|
||||
return r.Typ
|
||||
}
|
||||
|
||||
type SexpReflect struct {
|
||||
Val reflect.Value
|
||||
}
|
||||
|
||||
func (r *SexpReflect) Type() *RegisteredType {
|
||||
k := reflectName(reflect.Value(r.Val))
|
||||
Q("SexpReflect.Type() looking up type named '%s'", k)
|
||||
ty, ok := GoStructRegistry.Registry[k]
|
||||
if !ok {
|
||||
Q("SexpReflect.Type(): type named '%s' not found", k)
|
||||
return nil
|
||||
}
|
||||
Q("SexpReflect.Type(): type named '%s' found as regtype '%v'", k, ty.SexpString(nil))
|
||||
return ty
|
||||
}
|
||||
|
||||
type SexpError struct {
|
||||
error
|
||||
}
|
||||
|
||||
func (r *SexpError) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["error"]
|
||||
}
|
||||
|
||||
func (r *SexpSentinel) Type() *RegisteredType {
|
||||
return nil // TODO what should this be?
|
||||
}
|
||||
|
||||
type SexpClosureEnv Scope
|
||||
|
||||
func (r *SexpClosureEnv) Type() *RegisteredType {
|
||||
return nil // TODO what should this be?
|
||||
}
|
||||
|
||||
func (c *SexpClosureEnv) SexpString(ps *PrintState) string {
|
||||
scop := (*Scope)(c)
|
||||
s, err := scop.Show(scop.env, ps, "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type SexpSentinel struct {
|
||||
Val int
|
||||
}
|
||||
|
||||
// these are values now so that they also have addresses.
|
||||
var SexpNull = &SexpSentinel{Val: 0}
|
||||
var SexpEnd = &SexpSentinel{Val: 1}
|
||||
var SexpMarker = &SexpSentinel{Val: 2}
|
||||
|
||||
type SexpSemicolon struct{}
|
||||
type SexpComma struct{}
|
||||
|
||||
func (r *SexpSemicolon) Type() *RegisteredType {
|
||||
return nil // TODO what should this be?
|
||||
}
|
||||
|
||||
func (s *SexpSemicolon) SexpString(ps *PrintState) string {
|
||||
return ";"
|
||||
}
|
||||
|
||||
func (r *SexpComma) Type() *RegisteredType {
|
||||
return nil // TODO what should this be?
|
||||
}
|
||||
|
||||
func (s *SexpComma) SexpString(ps *PrintState) string {
|
||||
return ","
|
||||
}
|
||||
|
||||
func (sent *SexpSentinel) SexpString(ps *PrintState) string {
|
||||
if sent == SexpNull {
|
||||
return "nil"
|
||||
}
|
||||
if sent == SexpEnd {
|
||||
return "End"
|
||||
}
|
||||
if sent == SexpMarker {
|
||||
return "Marker"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func Cons(a Sexp, b Sexp) *SexpPair {
|
||||
return &SexpPair{a, b}
|
||||
}
|
||||
|
||||
func (pair *SexpPair) SexpString(ps *PrintState) string {
|
||||
str := "("
|
||||
|
||||
for {
|
||||
switch pair.Tail.(type) {
|
||||
case *SexpPair:
|
||||
str += pair.Head.SexpString(ps) + " "
|
||||
pair = pair.Tail.(*SexpPair)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
str += pair.Head.SexpString(ps)
|
||||
|
||||
if pair.Tail == SexpNull {
|
||||
str += ")"
|
||||
} else {
|
||||
str += " \\ " + pair.Tail.SexpString(ps) + ")"
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
func (r *SexpPair) Type() *RegisteredType {
|
||||
return nil // TODO what should this be?
|
||||
}
|
||||
|
||||
type SexpArray struct {
|
||||
Val []Sexp
|
||||
|
||||
Typ *RegisteredType
|
||||
|
||||
IsFuncDeclTypeArray bool
|
||||
Infix bool
|
||||
|
||||
Env *Zlisp
|
||||
}
|
||||
|
||||
func (r *SexpArray) Type() *RegisteredType {
|
||||
if r.Typ == nil {
|
||||
if len(r.Val) > 0 {
|
||||
// take type from first element
|
||||
ty := r.Val[0].Type()
|
||||
if ty != nil {
|
||||
r.Typ = GoStructRegistry.GetOrCreateSliceType(ty)
|
||||
}
|
||||
} else {
|
||||
// empty array
|
||||
r.Typ = GoStructRegistry.Lookup("[]")
|
||||
//P("lookup [] returned type %#v", r.Typ)
|
||||
}
|
||||
}
|
||||
return r.Typ
|
||||
}
|
||||
|
||||
func (arr *SexpArray) SexpString(ps *PrintState) string {
|
||||
indInner := ""
|
||||
indent := ps.GetIndent()
|
||||
innerPs := ps.AddIndent(4) // generates a fresh new PrintState
|
||||
inner := indent + 4
|
||||
//prettyEnd := ""
|
||||
pretty := false
|
||||
if arr != nil && arr.Env != nil && arr.Env.Pretty {
|
||||
pretty = true
|
||||
//prettyEnd = "\n"
|
||||
indInner = strings.Repeat(" ", inner)
|
||||
ps = innerPs
|
||||
}
|
||||
|
||||
opn := "["
|
||||
cls := "]"
|
||||
if arr.Infix {
|
||||
opn = "{"
|
||||
cls = "}"
|
||||
}
|
||||
if pretty {
|
||||
opn += "\n"
|
||||
indInner = strings.Repeat(" ", inner)
|
||||
}
|
||||
|
||||
if len(arr.Val) == 0 {
|
||||
return opn + cls
|
||||
}
|
||||
ta := arr.IsFuncDeclTypeArray
|
||||
str := opn
|
||||
for i, sexp := range arr.Val {
|
||||
str += indInner + sexp.SexpString(ps)
|
||||
if ta && i%2 == 0 {
|
||||
str += ":"
|
||||
} else {
|
||||
str += " "
|
||||
}
|
||||
}
|
||||
m := len(str)
|
||||
str = str[:m-1] + indInner + cls
|
||||
return str
|
||||
}
|
||||
|
||||
func (e *SexpError) SexpString(ps *PrintState) string {
|
||||
return e.error.Error()
|
||||
}
|
||||
|
||||
type EmbedPath struct {
|
||||
ChildName string
|
||||
ChildFieldNum int
|
||||
}
|
||||
|
||||
func GetEmbedPath(e []EmbedPath) string {
|
||||
r := ""
|
||||
last := len(e) - 1
|
||||
for i, s := range e {
|
||||
r += s.ChildName
|
||||
if i < last {
|
||||
r += ":"
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type HashFieldDet struct {
|
||||
FieldNum int
|
||||
FieldType reflect.Type
|
||||
StructField reflect.StructField
|
||||
FieldName string
|
||||
FieldJsonTag string
|
||||
EmbedPath []EmbedPath // we are embedded if len(EmbedPath) > 0
|
||||
}
|
||||
type SexpHash struct {
|
||||
TypeName string
|
||||
Map map[int][]*SexpPair
|
||||
KeyOrder []Sexp
|
||||
GoStructFactory *RegisteredType
|
||||
NumKeys int
|
||||
GoMethods []reflect.Method
|
||||
GoFields []reflect.StructField
|
||||
GoMethSx SexpArray
|
||||
GoFieldSx SexpArray
|
||||
GoType reflect.Type
|
||||
NumMethod int
|
||||
GoShadowStruct interface{}
|
||||
GoShadowStructVa reflect.Value
|
||||
ShadowSet bool
|
||||
|
||||
// json tag name -> pointers to example values, as factories for SexpToGoStructs()
|
||||
JsonTagMap map[string]*HashFieldDet
|
||||
DetOrder []*HashFieldDet
|
||||
|
||||
// for using these as a scoping model
|
||||
DefnEnv *SexpHash
|
||||
SuperClass *SexpHash
|
||||
ZMain SexpFunction
|
||||
ZMethods map[string]*SexpFunction
|
||||
Env *Zlisp
|
||||
}
|
||||
|
||||
var MethodNotFound = fmt.Errorf("method not found")
|
||||
|
||||
func (h *SexpHash) RunZmethod(method string, args []Sexp) (Sexp, error) {
|
||||
f, ok := (h.ZMethods)[method]
|
||||
if !ok {
|
||||
return SexpNull, MethodNotFound
|
||||
}
|
||||
|
||||
panic(fmt.Errorf("not done calling %s", f.name))
|
||||
//return SexpNull, nil
|
||||
}
|
||||
|
||||
func CallZMethodOnRecordFunction(env *Zlisp, name string, args []Sexp) (Sexp, error) {
|
||||
narg := len(args)
|
||||
if narg < 2 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
var hash *SexpHash
|
||||
switch h := args[0].(type) {
|
||||
case *SexpHash:
|
||||
hash = h
|
||||
default:
|
||||
return SexpNull, fmt.Errorf("can only _call on a record")
|
||||
}
|
||||
|
||||
method := ""
|
||||
switch s := args[1].(type) {
|
||||
case *SexpSymbol:
|
||||
method = s.name
|
||||
case *SexpStr:
|
||||
method = s.S
|
||||
default:
|
||||
return SexpNull, fmt.Errorf("can only _call with a " +
|
||||
"symbol or string as the method name. example: (_call record method:)")
|
||||
}
|
||||
|
||||
return hash.RunZmethod(method, args[2:])
|
||||
}
|
||||
|
||||
func (h *SexpHash) SetMain(p *SexpFunction) {
|
||||
h.BindSymbol(h.Env.MakeSymbol(".main"), p)
|
||||
}
|
||||
|
||||
func (h *SexpHash) SetDefnEnv(p *SexpHash) {
|
||||
h.DefnEnv = p
|
||||
h.BindSymbol(h.Env.MakeSymbol(".parent"), p)
|
||||
}
|
||||
|
||||
func (h *SexpHash) Lookup(env *Zlisp, key Sexp) (expr Sexp, err error) {
|
||||
return h.HashGet(env, key)
|
||||
}
|
||||
|
||||
func (h *SexpHash) BindSymbol(key *SexpSymbol, val Sexp) error {
|
||||
return h.HashSet(key, val)
|
||||
}
|
||||
|
||||
func (h *SexpHash) SetGoStructFactory(factory *RegisteredType) {
|
||||
h.GoStructFactory = factory
|
||||
}
|
||||
|
||||
var SexpIntSize = 64
|
||||
var SexpFloatSize = 64
|
||||
|
||||
func (r *SexpReflect) SexpString(ps *PrintState) string {
|
||||
Q("in SexpReflect.SexpString(indent); top; type = %T", r)
|
||||
if reflect.Value(r.Val).Type().Kind() == reflect.Ptr {
|
||||
iface := reflect.Value(r.Val).Interface()
|
||||
switch iface.(type) {
|
||||
case *string:
|
||||
return fmt.Sprintf("`%v`", reflect.Value(r.Val).Elem().Interface())
|
||||
default:
|
||||
return fmt.Sprintf("%v", reflect.Value(r.Val).Elem().Interface())
|
||||
}
|
||||
}
|
||||
iface := reflect.Value(r.Val).Interface()
|
||||
Q("in SexpReflect.SexpString(indent); type = %T", iface)
|
||||
switch iface.(type) {
|
||||
default:
|
||||
return fmt.Sprintf("%v", iface)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *SexpBool) SexpString(ps *PrintState) string {
|
||||
if bool(b.Val) {
|
||||
return "true"
|
||||
}
|
||||
return "false"
|
||||
}
|
||||
|
||||
func (i *SexpInt) SexpString(ps *PrintState) string {
|
||||
return strconv.Itoa(int(i.Val))
|
||||
}
|
||||
|
||||
func (i *SexpUint64) SexpString(ps *PrintState) string {
|
||||
return strconv.FormatUint(i.Val, 10) + "ULL"
|
||||
}
|
||||
|
||||
func (f *SexpFloat) SexpString(ps *PrintState) string {
|
||||
if f.Scientific {
|
||||
return strconv.FormatFloat(f.Val, 'e', -1, SexpFloatSize)
|
||||
}
|
||||
return strconv.FormatFloat(f.Val, 'f', -1, SexpFloatSize)
|
||||
}
|
||||
|
||||
func (c *SexpChar) SexpString(ps *PrintState) string {
|
||||
return strconv.QuoteRune(c.Val)
|
||||
}
|
||||
|
||||
func (s *SexpStr) SexpString(ps *PrintState) string {
|
||||
if s.backtick {
|
||||
return "`" + s.S + "`"
|
||||
}
|
||||
return strconv.Quote(string(s.S))
|
||||
}
|
||||
|
||||
func (r *SexpRaw) SexpString(ps *PrintState) string {
|
||||
return fmt.Sprintf("%#v", []byte(r.Val))
|
||||
}
|
||||
|
||||
type SexpSymbol struct {
|
||||
name string
|
||||
number int
|
||||
isDot bool
|
||||
isSigil bool
|
||||
colonTail bool
|
||||
sigil string
|
||||
}
|
||||
|
||||
func (sym *SexpSymbol) RHS(env *Zlisp) (Sexp, error) {
|
||||
if sym.isDot && env != nil {
|
||||
return dotGetSetHelper(env, sym.name, nil)
|
||||
}
|
||||
return sym, nil
|
||||
}
|
||||
|
||||
func (sym *SexpSymbol) AssignToSelection(env *Zlisp, rhs Sexp) error {
|
||||
if sym.isDot && env != nil {
|
||||
_, err := dotGetSetHelper(env, sym.name, &rhs)
|
||||
return err
|
||||
}
|
||||
panic("not implemented yet")
|
||||
}
|
||||
|
||||
func (sym *SexpSymbol) SexpString(ps *PrintState) string {
|
||||
if sym.colonTail {
|
||||
// return sym.name + ":"
|
||||
}
|
||||
return sym.name
|
||||
}
|
||||
|
||||
func (r *SexpSymbol) Type() *RegisteredType {
|
||||
return GoStructRegistry.Registry["symbol"]
|
||||
}
|
||||
|
||||
func (sym SexpSymbol) Name() string {
|
||||
return sym.name
|
||||
}
|
||||
|
||||
func (sym SexpSymbol) Number() int {
|
||||
return sym.number
|
||||
}
|
||||
|
||||
// SexpInterfaceDecl
|
||||
type SexpInterfaceDecl struct {
|
||||
name string
|
||||
methods []*SexpFunction
|
||||
}
|
||||
|
||||
func (r *SexpInterfaceDecl) SexpString(ps *PrintState) string {
|
||||
indent := ps.GetIndent()
|
||||
space := strings.Repeat(" ", indent)
|
||||
space4 := strings.Repeat(" ", indent+4)
|
||||
s := space + "(interface " + r.name + " ["
|
||||
if len(r.methods) > 0 {
|
||||
s += "\n"
|
||||
}
|
||||
for i := range r.methods {
|
||||
s += space4 + r.methods[i].SexpString(ps.AddIndent(4)) + "\n"
|
||||
}
|
||||
s += space + "])"
|
||||
return s
|
||||
}
|
||||
|
||||
func (r *SexpInterfaceDecl) Type() *RegisteredType {
|
||||
// todo: how to register/what to register?
|
||||
return GoStructRegistry.Registry[r.name]
|
||||
}
|
||||
|
||||
// SexpFunction
|
||||
type SexpFunction struct {
|
||||
name string
|
||||
user bool
|
||||
nargs int
|
||||
varargs bool
|
||||
fun ZlispFunction
|
||||
userfun ZlispUserFunction
|
||||
orig Sexp
|
||||
closingOverScopes *Closing
|
||||
parent *SexpFunction
|
||||
isBuilder bool // see defbuild; builders are builtins that receive un-evaluated expressions
|
||||
inputTypes *SexpHash
|
||||
returnTypes *SexpHash
|
||||
hasBody bool // could just be declaration in an interface, without a body
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) Type() *RegisteredType {
|
||||
return nil // TODO what goes here
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) Copy() *SexpFunction {
|
||||
cp := *sf
|
||||
return &cp
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) SetClosing(clos *Closing) {
|
||||
ps4 := NewPrintStateWithIndent(4)
|
||||
pre, err := sf.ShowClosing(clos.env, ps4, "prev")
|
||||
_ = pre
|
||||
panicOn(err)
|
||||
newnew, err := sf.ShowClosing(clos.env, ps4, "newnew")
|
||||
_ = newnew
|
||||
panicOn(err)
|
||||
//P("99999 for sfun = %p, in sfun.SetClosing(), prev value is %p = '%s'\n",
|
||||
// sf, sf.closingOverScopes, pre)
|
||||
//P("88888 in sfun.SetClosing(), new value is %p = '%s'\n", clos, newnew)
|
||||
sf.closingOverScopes = clos
|
||||
//P("in SetClosing() for '%s'/%p: my stack is: '%s'", sf.name, sf, clos.Stack.SexpString(nil))
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) ShowClosing(env *Zlisp, ps *PrintState, label string) (string, error) {
|
||||
if sf.closingOverScopes == nil {
|
||||
return sf.name + " has no captured scopes.", nil
|
||||
}
|
||||
return sf.closingOverScopes.Show(env, ps, label)
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) ClosingLookupSymbolUntilFunction(sym *SexpSymbol) (Sexp, error, *Scope) {
|
||||
if sf.closingOverScopes != nil {
|
||||
return sf.closingOverScopes.LookupSymbolUntilFunction(sym, nil, 1, false)
|
||||
}
|
||||
return SexpNull, SymNotFound, nil
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) ClosingLookupSymbol(sym *SexpSymbol, setVal *Sexp) (Sexp, error, *Scope) {
|
||||
if sf.closingOverScopes != nil {
|
||||
return sf.closingOverScopes.LookupSymbol(sym, setVal)
|
||||
}
|
||||
//P("sf.closingOverScopes was nil, no captured scopes. sf = '%v'", sf.SexpString(nil))
|
||||
return SexpNull, SymNotFound, nil
|
||||
}
|
||||
|
||||
// chase parent pointers up the chain and check each of their immediate closures.
|
||||
func (sf *SexpFunction) LookupSymbolInParentChainOfClosures(sym *SexpSymbol, setVal *Sexp, env *Zlisp) (Sexp, error, *Scope) {
|
||||
|
||||
cur := sf
|
||||
par := sf.parent
|
||||
for par != nil {
|
||||
//fmt.Printf(" parent chain: cur:%v -> parent:%v\n", cur.name, par.name)
|
||||
//fmt.Printf(" cur.closures = %s", ClosureToString(cur, env))
|
||||
|
||||
exp, err, scope := cur.ClosingLookupSymbolUntilFunc(sym, setVal, 1, false)
|
||||
if err == nil {
|
||||
//P("LookupSymbolInParentChainOfClosures(sym='%s') found in scope '%s'\n", sym.name, scope.Name)
|
||||
return exp, err, scope
|
||||
}
|
||||
|
||||
cur = par
|
||||
par = par.parent
|
||||
}
|
||||
|
||||
return SexpNull, SymNotFound, nil
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) ClosingLookupSymbolUntilFunc(sym *SexpSymbol, setVal *Sexp, maximumFuncToSearch int, checkCaptures bool) (Sexp, error, *Scope) {
|
||||
if sf.closingOverScopes != nil {
|
||||
return sf.closingOverScopes.LookupSymbolUntilFunction(sym, setVal, maximumFuncToSearch, checkCaptures)
|
||||
}
|
||||
//P("sf.closingOverScopes was nil, no captured scopes. sf = '%v'", sf.SexpString(nil))
|
||||
return SexpNull, SymNotFound, nil
|
||||
}
|
||||
|
||||
func (sf *SexpFunction) SexpString(ps *PrintState) string {
|
||||
if sf.orig == nil {
|
||||
return "fn [" + sf.name + "]"
|
||||
}
|
||||
return sf.orig.SexpString(ps)
|
||||
}
|
||||
|
||||
func IsTruthy(expr Sexp) bool {
|
||||
switch e := expr.(type) {
|
||||
case *SexpBool:
|
||||
return e.Val
|
||||
case *SexpInt:
|
||||
return e.Val != 0
|
||||
case *SexpUint64:
|
||||
return e.Val != 0
|
||||
case *SexpChar:
|
||||
return e.Val != 0
|
||||
case *SexpSentinel:
|
||||
return e != SexpNull
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type SexpStackmark struct {
|
||||
sym *SexpSymbol
|
||||
}
|
||||
|
||||
func (r *SexpStackmark) Type() *RegisteredType {
|
||||
return nil // TODO what should this be?
|
||||
}
|
||||
|
||||
func (mark *SexpStackmark) SexpString(ps *PrintState) string {
|
||||
return "stackmark " + mark.sym.name
|
||||
}
|
||||
Reference in New Issue
Block a user