environment.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. package glisp
  2. import (
  3. "bufio"
  4. "bytes"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "os"
  9. "strconv"
  10. )
  11. type PreHook func(*Glisp, string, []Sexp)
  12. type PostHook func(*Glisp, string, Sexp)
  13. type Glisp struct {
  14. datastack *Stack
  15. scopestack *Stack
  16. addrstack *Stack
  17. stackstack *Stack
  18. symtable map[string]int
  19. revsymtable map[int]string
  20. builtins map[int]SexpFunction
  21. macros map[int]SexpFunction
  22. curfunc SexpFunction
  23. mainfunc SexpFunction
  24. pc int
  25. nextsymbol int
  26. before []PreHook
  27. after []PostHook
  28. }
  29. const CallStackSize = 25
  30. const ScopeStackSize = 50
  31. const DataStackSize = 100
  32. const StackStackSize = 5
  33. func NewGlisp() *Glisp {
  34. env := new(Glisp)
  35. env.datastack = NewStack(DataStackSize)
  36. env.scopestack = NewStack(ScopeStackSize)
  37. env.scopestack.PushScope()
  38. env.stackstack = NewStack(StackStackSize)
  39. env.addrstack = NewStack(CallStackSize)
  40. env.builtins = make(map[int]SexpFunction)
  41. env.macros = make(map[int]SexpFunction)
  42. env.symtable = make(map[string]int)
  43. env.revsymtable = make(map[int]string)
  44. env.nextsymbol = 1
  45. env.before = []PreHook{}
  46. env.after = []PostHook{}
  47. for key, function := range BuiltinFunctions {
  48. sym := env.MakeSymbol(key)
  49. env.builtins[sym.number] = MakeUserFunction(key, function)
  50. env.AddFunction(key, function)
  51. }
  52. env.mainfunc = MakeFunction("__main", 0, false, make([]Instruction, 0))
  53. env.curfunc = env.mainfunc
  54. env.pc = 0
  55. return env
  56. }
  57. func (env *Glisp) Clone() *Glisp {
  58. dupenv := new(Glisp)
  59. dupenv.datastack = env.datastack.Clone()
  60. dupenv.stackstack = env.stackstack.Clone()
  61. dupenv.scopestack = env.scopestack.Clone()
  62. dupenv.addrstack = env.addrstack.Clone()
  63. dupenv.builtins = env.builtins
  64. dupenv.macros = env.macros
  65. dupenv.symtable = env.symtable
  66. dupenv.revsymtable = env.revsymtable
  67. dupenv.nextsymbol = env.nextsymbol
  68. dupenv.before = env.before
  69. dupenv.after = env.after
  70. dupenv.scopestack.Push(env.scopestack.elements[0])
  71. dupenv.mainfunc = MakeFunction("__main", 0, false, make([]Instruction, 0))
  72. dupenv.curfunc = dupenv.mainfunc
  73. dupenv.pc = 0
  74. return dupenv
  75. }
  76. func (env *Glisp) Duplicate() *Glisp {
  77. dupenv := new(Glisp)
  78. dupenv.datastack = NewStack(DataStackSize)
  79. dupenv.scopestack = NewStack(ScopeStackSize)
  80. dupenv.stackstack = NewStack(StackStackSize)
  81. dupenv.addrstack = NewStack(CallStackSize)
  82. dupenv.builtins = env.builtins
  83. dupenv.macros = env.macros
  84. dupenv.symtable = env.symtable
  85. dupenv.revsymtable = env.revsymtable
  86. dupenv.nextsymbol = env.nextsymbol
  87. dupenv.before = env.before
  88. dupenv.after = env.after
  89. dupenv.scopestack.Push(env.scopestack.elements[0])
  90. dupenv.mainfunc = MakeFunction("__main", 0, false, make([]Instruction, 0))
  91. dupenv.curfunc = dupenv.mainfunc
  92. dupenv.pc = 0
  93. return dupenv
  94. }
  95. func (env *Glisp) MakeSymbol(name string) SexpSymbol {
  96. symnum, ok := env.symtable[name]
  97. if ok {
  98. return SexpSymbol{name, symnum}
  99. }
  100. symbol := SexpSymbol{name, env.nextsymbol}
  101. env.symtable[name] = symbol.number
  102. env.revsymtable[symbol.number] = name
  103. env.nextsymbol++
  104. return symbol
  105. }
  106. func (env *Glisp) GenSymbol(prefix string) SexpSymbol {
  107. symname := prefix + strconv.Itoa(env.nextsymbol)
  108. return env.MakeSymbol(symname)
  109. }
  110. func (env *Glisp) CurrentFunctionSize() int {
  111. if env.curfunc.user {
  112. return 0
  113. }
  114. return len(env.curfunc.fun)
  115. }
  116. func (env *Glisp) wrangleOptargs(fnargs, nargs int) error {
  117. if nargs < fnargs {
  118. return errors.New(
  119. fmt.Sprintf("Expected >%d arguments, got %d",
  120. fnargs, nargs))
  121. }
  122. if nargs > fnargs {
  123. optargs, err := env.datastack.PopExpressions(nargs - fnargs)
  124. if err != nil {
  125. return err
  126. }
  127. env.datastack.PushExpr(MakeList(optargs))
  128. } else {
  129. env.datastack.PushExpr(SexpNull)
  130. }
  131. return nil
  132. }
  133. func (env *Glisp) CallFunction(function SexpFunction, nargs int) error {
  134. for _, prehook := range env.before {
  135. expressions, err := env.datastack.GetExpressions(nargs)
  136. if err != nil {
  137. return err
  138. }
  139. prehook(env, function.name, expressions)
  140. }
  141. if function.varargs {
  142. err := env.wrangleOptargs(function.nargs, nargs)
  143. if err != nil {
  144. return err
  145. }
  146. } else if nargs != function.nargs {
  147. return errors.New(
  148. fmt.Sprintf("%s expected %d arguments, got %d",
  149. function.name, function.nargs, nargs))
  150. }
  151. if env.scopestack.IsEmpty() {
  152. panic("where's the global scope?")
  153. }
  154. globalScope := env.scopestack.elements[0]
  155. env.stackstack.Push(env.scopestack)
  156. env.scopestack = NewStack(ScopeStackSize)
  157. env.scopestack.Push(globalScope)
  158. if function.closeScope != nil {
  159. function.closeScope.PushAllTo(env.scopestack)
  160. }
  161. env.addrstack.PushAddr(env.curfunc, env.pc+1)
  162. env.scopestack.PushScope()
  163. env.curfunc = function
  164. env.pc = 0
  165. return nil
  166. }
  167. func (env *Glisp) ReturnFromFunction() error {
  168. for _, posthook := range env.after {
  169. retval, err := env.datastack.GetExpr(0)
  170. if err != nil {
  171. return err
  172. }
  173. posthook(env, env.curfunc.name, retval)
  174. }
  175. var err error
  176. env.curfunc, env.pc, err = env.addrstack.PopAddr()
  177. if err != nil {
  178. return err
  179. }
  180. scopestack, err := env.stackstack.Pop()
  181. if err != nil {
  182. return err
  183. }
  184. env.scopestack = scopestack.(*Stack)
  185. return nil
  186. }
  187. func (env *Glisp) CallUserFunction(
  188. function SexpFunction, name string, nargs int) error {
  189. for _, prehook := range env.before {
  190. expressions, err := env.datastack.GetExpressions(nargs)
  191. if err != nil {
  192. return err
  193. }
  194. prehook(env, function.name, expressions)
  195. }
  196. args, err := env.datastack.PopExpressions(nargs)
  197. if err != nil {
  198. return errors.New(
  199. fmt.Sprintf("Error calling %s: %v", name, err))
  200. }
  201. env.addrstack.PushAddr(env.curfunc, env.pc+1)
  202. env.curfunc = function
  203. env.pc = -1
  204. res, err := function.userfun(env, name, args)
  205. if err != nil {
  206. return errors.New(
  207. fmt.Sprintf("Error calling %s: %v", name, err))
  208. }
  209. env.datastack.PushExpr(res)
  210. for _, posthook := range env.after {
  211. posthook(env, name, res)
  212. }
  213. env.curfunc, env.pc, _ = env.addrstack.PopAddr()
  214. return nil
  215. }
  216. func (env *Glisp) ParseStream(in io.Reader) ([]Sexp, error) {
  217. lexer := NewLexerFromStream(bufio.NewReader(in))
  218. var err error
  219. var exp []Sexp
  220. exp, err = ParseTokens(env, lexer)
  221. if err != nil {
  222. return nil, fmt.Errorf("Error on line %d: %v\n", lexer.Linenum(), err)
  223. }
  224. return exp, nil
  225. }
  226. // ParseFile, used in the generator at read time to dynamiclly add more defs from other files
  227. func (env *Glisp) ParseFile(file string) ([]Sexp, error) {
  228. in, err := os.Open(file)
  229. if err != nil {
  230. return nil, err
  231. }
  232. var exp []Sexp
  233. exp, err = env.ParseStream(in)
  234. in.Close()
  235. return exp, err
  236. }
  237. func (env *Glisp) SourceExpressions(expressions []Sexp) error {
  238. gen := NewGenerator(env)
  239. if !env.ReachedEnd() {
  240. gen.AddInstruction(PopInstr(0))
  241. }
  242. err := gen.GenerateBegin(expressions)
  243. if err != nil {
  244. return err
  245. }
  246. curfunc := env.curfunc
  247. curpc := env.pc
  248. env.curfunc = MakeFunction("__source", 0, false, gen.instructions)
  249. env.pc = 0
  250. env.datastack.PushExpr(SexpNull)
  251. if _, err = env.Run(); err != nil {
  252. return err
  253. }
  254. env.datastack.PopExpr()
  255. env.pc = curpc
  256. env.curfunc = curfunc
  257. return nil
  258. }
  259. // SourceStream, load this in via a __source dynamic function, after it runs it no longer exists
  260. func (env *Glisp) SourceStream(stream io.Reader) error {
  261. expressions, err := env.ParseStream(stream)
  262. if err != nil {
  263. return err
  264. }
  265. return env.SourceExpressions(expressions)
  266. }
  267. func (env *Glisp) SourceFile(file *os.File) error {
  268. return env.SourceStream(bufio.NewReader(file))
  269. }
  270. func (env *Glisp) LoadExpressions(expressions []Sexp) error {
  271. gen := NewGenerator(env)
  272. if !env.ReachedEnd() {
  273. gen.AddInstruction(PopInstr(0))
  274. }
  275. err := gen.GenerateBegin(expressions)
  276. if err != nil {
  277. return err
  278. }
  279. env.mainfunc.fun = append(env.mainfunc.fun, gen.instructions...)
  280. env.curfunc = env.mainfunc
  281. return nil
  282. }
  283. // LoadStream, load this in via running a __main function and setting main on the environment
  284. func (env *Glisp) LoadStream(stream io.Reader) error {
  285. expressions, err := env.ParseStream(stream)
  286. if err != nil {
  287. return err
  288. }
  289. return env.LoadExpressions(expressions)
  290. }
  291. func (env *Glisp) EvalString(str string) (Sexp, error) {
  292. err := env.LoadString(str)
  293. if err != nil {
  294. return SexpNull, err
  295. }
  296. return env.Run()
  297. }
  298. func (env *Glisp) LoadFile(file *os.File) error {
  299. return env.LoadStream(bufio.NewReader(file))
  300. }
  301. func (env *Glisp) LoadString(str string) error {
  302. return env.LoadStream(bytes.NewBuffer([]byte(str)))
  303. }
  304. func (env *Glisp) AddFunction(name string, function GlispUserFunction) {
  305. env.AddGlobal(name, MakeUserFunction(name, function))
  306. }
  307. func (env *Glisp) AddGlobal(name string, obj Sexp) {
  308. sym := env.MakeSymbol(name)
  309. env.scopestack.elements[0].(Scope)[sym.number] = obj
  310. }
  311. func (env *Glisp) AddMacro(name string, function GlispUserFunction) {
  312. sym := env.MakeSymbol(name)
  313. env.macros[sym.number] = MakeUserFunction(name, function)
  314. }
  315. func (env *Glisp) ImportEval() {
  316. env.AddFunction("source-file", SourceFileFunction)
  317. env.AddFunction("eval", EvalFunction)
  318. }
  319. func (env *Glisp) DumpFunctionByName(name string) error {
  320. obj, found := env.FindObject(name)
  321. if !found {
  322. return errors.New(fmt.Sprintf("%q not found", name))
  323. }
  324. var fun GlispFunction
  325. switch t := obj.(type) {
  326. case SexpFunction:
  327. if !t.user {
  328. fun = t.fun
  329. } else {
  330. return errors.New("not a glisp function")
  331. }
  332. default:
  333. return errors.New("not a function")
  334. }
  335. DumpFunction(fun)
  336. return nil
  337. }
  338. func DumpFunction(fun GlispFunction) {
  339. for _, instr := range fun {
  340. fmt.Println("\t" + instr.InstrString())
  341. }
  342. }
  343. func (env *Glisp) DumpEnvironment() {
  344. fmt.Println("Instructions:")
  345. if !env.curfunc.user {
  346. DumpFunction(env.curfunc.fun)
  347. }
  348. fmt.Println("Stack:")
  349. env.datastack.PrintStack()
  350. fmt.Printf("PC: %d\n", env.pc)
  351. }
  352. func (env *Glisp) ReachedEnd() bool {
  353. return env.pc == env.CurrentFunctionSize()
  354. }
  355. func (env *Glisp) GetStackTrace(err error) string {
  356. str := fmt.Sprintf("error in %s:%d: %v\n",
  357. env.curfunc.name, env.pc, err)
  358. for !env.addrstack.IsEmpty() {
  359. fun, pos, _ := env.addrstack.PopAddr()
  360. str += fmt.Sprintf("in %s:%d\n", fun.name, pos)
  361. }
  362. return str
  363. }
  364. func (env *Glisp) Clear() {
  365. env.datastack.tos = -1
  366. env.scopestack.tos = 0
  367. env.addrstack.tos = -1
  368. env.mainfunc = MakeFunction("__main", 0, false, make([]Instruction, 0))
  369. env.curfunc = env.mainfunc
  370. env.pc = 0
  371. }
  372. func (env *Glisp) FindObject(name string) (Sexp, bool) {
  373. sym := env.MakeSymbol(name)
  374. obj, err := env.scopestack.LookupSymbol(sym)
  375. if err != nil {
  376. return SexpNull, false
  377. }
  378. return obj, true
  379. }
  380. func (env *Glisp) Apply(fun SexpFunction, args []Sexp) (Sexp, error) {
  381. if fun.user {
  382. return fun.userfun(env, fun.name, args)
  383. }
  384. env.pc = -2
  385. for _, expr := range args {
  386. env.datastack.PushExpr(expr)
  387. }
  388. //log.Print("Apply Calling ", fun, " with ", len(args))
  389. err := env.CallFunction(fun, len(args))
  390. if err != nil {
  391. return SexpNull, err
  392. }
  393. return env.Run()
  394. }
  395. func (env *Glisp) Run() (Sexp, error) {
  396. for env.pc != -1 && !env.ReachedEnd() {
  397. instr := env.curfunc.fun[env.pc]
  398. err := instr.Execute(env)
  399. if err != nil {
  400. return SexpNull, err
  401. }
  402. }
  403. if env.datastack.IsEmpty() {
  404. env.DumpEnvironment()
  405. os.Exit(-1)
  406. }
  407. return env.datastack.PopExpr()
  408. }
  409. func (env *Glisp) AddPreHook(fun PreHook) {
  410. env.before = append(env.before, fun)
  411. }
  412. func (env *Glisp) AddPostHook(fun PostHook) {
  413. env.after = append(env.after, fun)
  414. }