builtin.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. package muesli
  2. import "runtime"
  3. import "strings"
  4. import "sort"
  5. type LogTracer struct {
  6. }
  7. func (t LogTracer) Trace(vm VM, fmt string, args ... interface{}) bool {
  8. args = append([]interface{}{vm.BackTrace()}, args...)
  9. vm.Log("TRACE", "builtin.go", 12, "%s: " + vm.BackTrace() + fmt, args...)
  10. return false
  11. }
  12. type FmtTracer struct {
  13. }
  14. func (t FmtTracer) Trace(vm VM, fm string, args ... interface{}) bool {
  15. args = append([]interface{}{vm.BackTrace()}, args...)
  16. vm.Printf("%s: " + fm + "\n", args...)
  17. return false
  18. }
  19. func printf(vm *VM, args ...Value) []Value {
  20. var format string
  21. rest, err := ParseArgs(args, &format)
  22. if err != nil {
  23. return Fail(err)
  24. }
  25. extra := ListFromList(rest)
  26. vm.Printf(format, extra...)
  27. return None()
  28. }
  29. func println(vm *VM, args ...Value) []Value {
  30. var msg string
  31. _, err := ParseArgs(args, &msg)
  32. if err != nil {
  33. return Fail(err)
  34. } else {
  35. vm.Println(msg)
  36. }
  37. return None()
  38. }
  39. func p(vm *VM, args ...Value) []Value {
  40. for _, arg := range args {
  41. vm.Printf("%v\n", arg)
  42. }
  43. return None()
  44. }
  45. func trace(vm *VM, args ...Value) []Value {
  46. var b bool = true
  47. vm.Printf("command trace: %v\n", args)
  48. _, err := ParseArgs(args, &b)
  49. if err != nil {
  50. vm.Printf("Error: %s\n", err.Error())
  51. return Fail(err)
  52. }
  53. vm.Printf("command trace: bool: %v\n", b)
  54. if b {
  55. vm.Tracer = vm.Console // FmtTracer{}
  56. } else {
  57. vm.Tracer = nil
  58. }
  59. return Ok(BoolValue(b))
  60. }
  61. func sumi(vm *VM, args ...Value) []Value {
  62. slice, err := ParseArgsToIntSlice(args)
  63. if err != nil {
  64. vm.Printf("Error: %s\n", err.Error())
  65. return Fail(err)
  66. }
  67. res := int(0)
  68. for _, val := range slice {
  69. res += val
  70. }
  71. return IntOk(res)
  72. }
  73. func sumf(vm *VM, args ...Value) []Value {
  74. slice, err := ParseArgsToFloat64Slice(args)
  75. if err != nil {
  76. vm.Printf("Error: %s\n", err.Error())
  77. return Fail(err)
  78. }
  79. res := float64(0)
  80. for _, val := range slice {
  81. res += val
  82. }
  83. return FloatOk(res)
  84. }
  85. func addi(vm *VM, args ...Value) []Value {
  86. var v1, v2 int
  87. ParseArgs(args, &v1, &v2)
  88. return IntOk(v1 + v2)
  89. }
  90. func addf(vm *VM, args ...Value) []Value {
  91. var v1, v2 float64
  92. _, err := ParseArgs(args, &v1, &v2)
  93. if err != nil {
  94. return Fail(err)
  95. }
  96. return FloatOk(v1 + v2)
  97. }
  98. func subi(vm *VM, args ...Value) []Value {
  99. var v1, v2 int
  100. _, err := ParseArgs(args, &v1, &v2)
  101. if err != nil {
  102. return Fail(err)
  103. }
  104. return IntOk(v1 - v2)
  105. }
  106. func subf(vm *VM, args ...Value) []Value {
  107. var v1, v2 float64
  108. _, err := ParseArgs(args, &v1, &v2)
  109. if err != nil {
  110. return Fail(err)
  111. }
  112. return FloatOk(v1 - v2)
  113. }
  114. func muli(vm *VM, args ...Value) []Value {
  115. var v1, v2 int
  116. _, err := ParseArgs(args, &v1, &v2)
  117. if err != nil {
  118. return Fail(err)
  119. }
  120. return IntOk(v1 * v2)
  121. }
  122. func mulf(vm *VM, args ...Value) []Value {
  123. var v1, v2 float64
  124. _, err := ParseArgs(args, &v1, &v2)
  125. if err != nil {
  126. return Fail(err)
  127. }
  128. return FloatOk(v1 * v2)
  129. }
  130. func divi(vm *VM, args ...Value) []Value {
  131. var v1, v2 int
  132. _, err := ParseArgs(args, &v1, &v2)
  133. if err != nil {
  134. return Fail(err)
  135. }
  136. return IntOk(v1 / v2)
  137. }
  138. func divf(vm *VM, args ...Value) []Value {
  139. var v1, v2 float64
  140. _, err := ParseArgs(args, &v1, &v2)
  141. if err != nil {
  142. return Fail(err)
  143. }
  144. return FloatOk(v1 / v2)
  145. }
  146. func andb(vm * VM, args ...Value) []Value {
  147. var v1, v2 bool
  148. _, err := ParseArgs(args, &v1, &v2)
  149. if err != nil {
  150. return Fail(err)
  151. }
  152. return BoolOk(v1 && v2)
  153. }
  154. func orb(vm * VM, args ...Value) []Value {
  155. var v1, v2 bool
  156. _, err := ParseArgs(args, &v1, &v2)
  157. if err != nil {
  158. return Fail(err)
  159. }
  160. return BoolOk(v1 || v2)
  161. }
  162. func val(vm *VM, args ...Value) []Value {
  163. if len(args) < 1 {
  164. return []Value{NewErrorValuef("val requres at least one argument.")}
  165. }
  166. return args
  167. }
  168. func builtin_return(vm *VM, args ...Value) []Value {
  169. vm.Frame.returned = true
  170. vm.Frame.results = args
  171. vm.Trace("Returning... %v", vm.Frame)
  172. return args
  173. }
  174. func to(vm *VM, args ...Value) []Value {
  175. var name string
  176. rest, err := ParseArgs(args, &name)
  177. if err != nil {
  178. return Fail(err)
  179. }
  180. if len(rest) < 1 {
  181. return Fail(NewErrorValuef("Need at least 2 arguments: %v", args))
  182. }
  183. last := rest[len(rest)-1]
  184. block, isBlock := last.(*BlockValue)
  185. if ! isBlock {
  186. return Fail(NewErrorValuef("Not a block: %v", last))
  187. }
  188. param := args[1:len(args)-1]
  189. sign, err := NewSignatureWithNames(param...)
  190. if err != nil {
  191. return Fail(NewErrorValuef("Could not parse arguments: %v: %s", name, err))
  192. }
  193. // To must register one level up.
  194. return Ok(vm.RegisterDefined(name, sign, block, 1))
  195. }
  196. func cover(vm *VM, args ...Value) []Value {
  197. var name, target string
  198. rest, err := ParseArgs(args, &name, &target)
  199. if err != nil {
  200. return Fail(err)
  201. }
  202. types := []TypeValue{}
  203. for i, arg := range rest {
  204. if typ, ok := arg.(TypeValue) ; ok {
  205. types = append(types, typ)
  206. } else {
  207. return Fail(NewErrorValuef("Argument %d: not a type: %v %s", i+2, arg, arg.String()))
  208. }
  209. }
  210. // Overload must be defined one scope up.
  211. err = vm.AddOverload(name, target, 1, types...)
  212. if err != nil {
  213. return Fail(err)
  214. }
  215. return Ok()
  216. }
  217. func types(vm *VM, args ...Value) []Value {
  218. result := []Value{}
  219. for _, arg := range args {
  220. typ := arg.Type()
  221. result = append(result, typ)
  222. }
  223. return Ok(NewListValue(result...))
  224. }
  225. func set(vm *VM, val ...Value) []Value {
  226. if len(val) < 2 {
  227. return Fail(vm.Errorf("set needs at least 2 arguments: received %v", val))
  228. }
  229. target := val[0].String()
  230. value := val[1]
  231. if target == "(" || target == "$" {
  232. if len(val) < 3 {
  233. return Fail(vm.Errorf("indirect get needs results: received %v", val))
  234. }
  235. target = val[1].String()
  236. value = val[2]
  237. }
  238. level := 1
  239. if len(val) > 2 {
  240. upval := val[2]
  241. if upval.Type() == IntType {
  242. upval.Convert(&level)
  243. } else if upval.String() == "top" {
  244. vm.RegisterTop(target, value)
  245. return Ok(value)
  246. }
  247. }
  248. vm.RegisterUp(target, value, level)
  249. return Ok(value)
  250. }
  251. func get(vm *VM, val ...Value) []Value {
  252. if len(val) < 1 {
  253. return Fail(vm.Errorf("get needs at least 1 argument"))
  254. }
  255. target := val[0].String()
  256. if target == "(" || target == "$" {
  257. if len(val) < 2 {
  258. return Fail(vm.Errorf("indirect get needs results: received %v", val))
  259. }
  260. target = val[1].String()
  261. }
  262. return Ok(vm.Lookup(target))
  263. }
  264. func addl(vm *VM, args ...Value) []Value {
  265. var value Value
  266. var list *ListValue
  267. _, err := ParseArgs(args, &list, &value)
  268. if err != nil {
  269. return Fail(err)
  270. }
  271. list.Append(value)
  272. return Ok(list)
  273. }
  274. func fetchl(vm *VM, args ...Value) []Value {
  275. var index int
  276. var list *ListValue
  277. _, err := ParseArgs(args, &list, &index)
  278. if err != nil {
  279. return Fail(err)
  280. }
  281. if (index < 0) || (index >= len(list.List)) {
  282. return Fail(vm.Errorf("index out of range: %d<->%d", index, len(list.List)))
  283. }
  284. return Ok(list.List[index])
  285. }
  286. func storel(vm *VM, args ...Value) []Value {
  287. var index int
  288. var list *ListValue
  289. rest, err := ParseArgs(args, &list, &index)
  290. if err != nil {
  291. return Fail(err)
  292. }
  293. if len(rest) < 1 {
  294. return Fail(vm.Errorf("fetch: need 3 arguments"))
  295. }
  296. if (index < 0) || (index >= len(list.List)) {
  297. return Fail(vm.Errorf("index out of range: %d<->%d", index, len(list.List)))
  298. }
  299. list.List[index] = rest[0]
  300. return Ok(list.List[index])
  301. }
  302. func fetchm(vm *VM, args ...Value) []Value {
  303. var index Value
  304. var hmap *MapValue
  305. _, err := ParseArgs(args, &hmap, &index)
  306. if err != nil {
  307. return Fail(err)
  308. }
  309. return Ok(hmap.Map[index])
  310. }
  311. func storem(vm *VM, args ...Value) []Value {
  312. var index Value
  313. var hmap *MapValue
  314. rest, err := ParseArgs(args, &hmap, &index)
  315. if err != nil {
  316. return Fail(err)
  317. }
  318. if len (rest) < 1 {
  319. return Fail(vm.Errorf("fetch: need 3 arguments"))
  320. }
  321. hmap.Map[index] = rest[0]
  322. return Ok(hmap.Map[index])
  323. }
  324. func newmap(vm *VM, args ...Value) []Value {
  325. result := make(map[Value] Value)
  326. for i := 1; i < len(args) ; i+=2 {
  327. result[args[i-1]] = args[i]
  328. }
  329. return Ok(NewMapValue(result))
  330. }
  331. func help(vm *VM, val ...Value) [] Value {
  332. if len(val) < 1 {
  333. vm.Printf("help <callable> will display help on the callable\n\nThe following commands are available:\n")
  334. helpers := vm.DefinedHelpers()
  335. sort.SliceStable(helpers, func(i, j int) bool {
  336. return helpers[i].HelperName() < helpers[j].HelperName()
  337. })
  338. for _, helper := range helpers {
  339. fl := strings.SplitN(helper.Help(),"\n", 2)
  340. vm.Printf("%s %s: \n", helper.HelperName(), fl[0])
  341. }
  342. return Ok()
  343. }
  344. targetName := val[0].String()
  345. target := vm.Lookup(targetName)
  346. if target == nil {
  347. vm.Printf("help: %s not found.\n", targetName)
  348. return Ok()
  349. }
  350. if helper, isHelper := target.(Helper) ; isHelper {
  351. if len(val) > 1 {
  352. helper.SetHelp(val[1].String())
  353. }
  354. help := helper.Help()
  355. if call, isCall := target.(Callable); isCall {
  356. vm.Printf("%s %s: %s.\n", targetName, call.Signature().String(), help)
  357. } else {
  358. vm.Printf("%s: %s.\n", targetName, help)
  359. }
  360. return Ok(StringValue(help))
  361. } else {
  362. vm.Printf("%s %s. No help available.\n", targetName, target.Type())
  363. }
  364. return Ok()
  365. }
  366. func explain(vm *VM, val ...Value) [] Value {
  367. var target, help string
  368. _, err := ParseArgs(val, &target, &help)
  369. if err != nil {
  370. return Fail(err)
  371. }
  372. err = vm.SetHelp(target, help)
  373. if err != nil {
  374. return Fail(err)
  375. }
  376. return Ok(StringValue(help))
  377. }
  378. func exit(vm *VM, val ...Value) [] Value {
  379. var code int
  380. _, err := ParseArgs(val, &code)
  381. if err != nil {
  382. runtime.Goexit()
  383. }
  384. vm.ExitStatus = code
  385. runtime.Goexit()
  386. return Ok()
  387. }
  388. func comma(vm * VM, val ...Value) []Value {
  389. vm.Printf("Comma arguments: %v\n", val)
  390. if len(val) < 2 {
  391. return Fail(vm.Errorf("Need at least 2 arguments"))
  392. }
  393. target := val[0]
  394. command := val[1]
  395. val[1] = target
  396. val = val[1:]
  397. if call, isCall := command.(Callable); isCall {
  398. return vm.CallCallable(call, val...)
  399. } else if name, isName := command.(WordValue) ; isName {
  400. return vm.CallNamed(name.String(), val...)
  401. } else {
  402. return Fail(vm.Errorf("Not callable: %v", command))
  403. }
  404. }
  405. func (vm *VM) RegisterBuiltinTypes() {
  406. vm.RegisterTop("Int", IntType)
  407. vm.RegisterTop("Float", FloatType)
  408. vm.RegisterTop("String",StringType)
  409. vm.RegisterTop("Bool", BoolType)
  410. vm.RegisterTop("Word", WordType)
  411. vm.RegisterTop("Error", ErrorType)
  412. vm.RegisterTop("Type", TypeType)
  413. vm.RegisterTop("Empty", EmptyType)
  414. vm.RegisterTop("List", ListType)
  415. vm.RegisterTop("Map", MapType)
  416. vm.RegisterTop("Any", AnyType)
  417. vm.RegisterTop("ZeroType", ZeroType)
  418. }
  419. func (vm *VM) RegisterBuiltins() {
  420. vm.RegisterBuiltinTypes()
  421. vm.RegisterBuiltinWithHelp("addl", addl, "adds an element to a list").Takes(ListType, AnyType).Returns(ListType)
  422. vm.RegisterBuiltinWithHelp("addi", addi, `adds two integers together`).Takes(IntType, IntType).Returns(BoolType)
  423. vm.RegisterBuiltinWithHelp("addf", addf, `adds two floats together`).Takes(FloatType, FloatType).Returns(FloatType)
  424. vm.RegisterBuiltinWithHelp("andb", andb, `returns true if all it's arguments are true`).Takes(BoolType, BoolType).Returns(BoolType)
  425. vm.RegisterBuiltin(",", comma)
  426. vm.RegisterBuiltin("cover", cover)
  427. vm.RegisterBuiltin("fetchl", fetchl).Takes(ListType, IntType).Returns(AnyType)
  428. vm.RegisterBuiltin("fetchm", fetchm).Takes(MapType, AnyType).Returns(AnyType)
  429. vm.RegisterBuiltin("sumi", sumi).Takes(IntType, IntType).Returns(IntType)
  430. vm.RegisterBuiltin("sumf", sumf).Takes(FloatType, FloatType).Returns(FloatType)
  431. vm.RegisterBuiltin("subi", subi).Takes(IntType, IntType).Returns(IntType)
  432. vm.RegisterBuiltin("subf", subf).Takes(FloatType, FloatType).Returns(FloatType)
  433. vm.RegisterBuiltin("divi", divi).Takes(IntType, IntType).Returns(IntType)
  434. vm.RegisterBuiltin("divf", divf).Takes(FloatType, FloatType).Returns(FloatType)
  435. vm.RegisterBuiltin("map", newmap)
  436. vm.RegisterBuiltin("muli", muli).Takes(IntType, IntType).Returns(IntType)
  437. vm.RegisterBuiltin("mulf", mulf).Takes(FloatType, FloatType).Returns(FloatType)
  438. vm.RegisterBuiltinWithHelp("orb", orb, `[Bool Bool] -> Bool: returns true if on of it's arguments is true`)
  439. // vm.RegisterCover("add")
  440. vm.RegisterBuiltin("p", p)
  441. vm.RegisterBuiltin("println", println)
  442. vm.RegisterBuiltin("printf", printf)
  443. vm.RegisterBuiltin("storel", storel).Takes(ListType, IntType).Returns(AnyType)
  444. vm.RegisterBuiltin("storem", storem).Takes(MapType, AnyType).Returns(AnyType)
  445. vm.RegisterBuiltin("trace", trace)
  446. vm.RegisterBuiltin("to", to)
  447. vm.RegisterBuiltin("types", types)
  448. vm.RegisterBuiltin("return", builtin_return)
  449. vm.RegisterBuiltin("val", val)
  450. vm.RegisterBuiltin("set", set)
  451. vm.RegisterBuiltin("get", get)
  452. vm.RegisterBuiltin("help", help)
  453. vm.RegisterBuiltin("explain", explain)
  454. vm.RegisterBuiltin("exit", exit)
  455. vm.AddOverloads("mul",
  456. Over("mulf", 0, FloatType, FloatType),
  457. Over("muli", 0, IntType, IntType),
  458. Over("mulf", 0, FloatType, IntType),
  459. Over("mulf", 0, IntType, FloatType))
  460. vm.AddOverloads("add",
  461. Over("addf", 0, FloatType, FloatType),
  462. Over("addi", 0, IntType, IntType),
  463. Over("addf", 0, FloatType, IntType),
  464. Over("addf", 0, IntType, FloatType))
  465. vm.AddOverloads("div",
  466. Over("divf", 0, FloatType, FloatType),
  467. Over("divi", 0, IntType, IntType),
  468. Over("divf", 0, FloatType, IntType),
  469. Over("divf", 0, IntType, FloatType))
  470. vm.AddOverloads("sub",
  471. Over("subf", 0, FloatType, FloatType),
  472. Over("subi", 0, IntType, IntType),
  473. Over("subf", 0, FloatType, IntType),
  474. Over("subf", 0, IntType, FloatType))
  475. vm.Alias("*", "mul")
  476. vm.Alias("+", "add")
  477. vm.Alias("/", "div")
  478. vm.Alias("-", "sub")
  479. vm.Alias("||", "orb")
  480. vm.Alias("&&", "andb")
  481. vm.SetHelp("mul", " Num: Multiplies two numbers. Cover for muli and mulf.")
  482. vm.AddOverloads("fetch",
  483. Over("fetchl", 0, ListType, IntType),
  484. Over("fetchm", 0, MapType, AnyType),
  485. )
  486. vm.SetHelp("fetch", " storage, index. Fetch value in storage at given index.")
  487. /*
  488. vm.AddOverloads("store",
  489. Over("storel", ListType, IntType, AnyType),
  490. Over("storem", MapType, AnyType, AnyType),
  491. )
  492. vm.SetHelp("store", " storage, index, value. Store value in storage at given index.")
  493. */
  494. RegisterDoor(vm)
  495. }