// Package forge implements sort of a stack-based interpreter. package forge import ( "io" "os" "git.sr.ht/~cco/go-scopes/common/ptr" "git.sr.ht/~cco/go-scopes/common/stack" "git.sr.ht/~cco/go-scopes/common/voc" ) type DataItem interface{} type Ptr = ptr.Ptr[DataItem] type Stack = stack.Stack[DataItem] type Voc = voc.Vocabulary[XT] type Callable func(*ForgeEnv, *Item) type Item struct { name string immediate bool fct Callable body Ptr } type XT = *Item type ForgeEnv struct { ds, rs Stack cp, ip, dp Ptr voc *Voc latestXT XT cstate bool output io.Writer } func NewVoc(parent *Voc) *Voc { return voc.NewVoc[XT](parent) } func NewFE() *ForgeEnv { return newFE(NewVoc(nil)) } func (f *ForgeEnv) ChildFE() *ForgeEnv { return newFE(NewVoc(f.voc)) } func newFE(voc *Voc) *ForgeEnv { return &ForgeEnv{ ds: stack.NewStack[DataItem](), rs: stack.NewStack[DataItem](), ip: ptr.NewSlice[DataItem](), voc: voc, output: os.Stdout, } } // ForgeEnv methods func (f *ForgeEnv) Exec() { } // dummy stuff for testing var builtins = struct{ add, sub XT }{} var work = struct{ square XT }{} func init() { builtins.add = &Item{} builtins.sub = &Item{} }