builtin.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. package muesli
  2. import "fmt"
  3. import "log"
  4. import "runtime"
  5. import "strings"
  6. import "sort"
  7. type LogTracer struct {
  8. }
  9. func (t LogTracer) Trace(vm VM, ast Ast, val ... Value) bool {
  10. log.Printf("Trace: %s -> %v", ast.String(), val)
  11. return false
  12. }
  13. type FmtTracer struct {
  14. }
  15. func (t FmtTracer) Trace(vm VM, ast Ast, args ... Value) bool {
  16. arg := args[0]
  17. rest := args[1:len(args)]
  18. fmt.Printf("Trace: %s: %v -> ", ast.String(), arg)
  19. for _, v := range rest {
  20. fmt.Printf("%v, ", v)
  21. }
  22. fmt.Printf("<-\n ")
  23. return false
  24. }
  25. func printf(vm *VM, args ...Value) []Value {
  26. var format string
  27. rest, err := ParseArgs(args, &format)
  28. if err != nil {
  29. return Fail(err)
  30. }
  31. extra := ListFromList(rest)
  32. fmt.Printf(format, extra...)
  33. return None()
  34. }
  35. func println(vm *VM, args ...Value) []Value {
  36. var msg string
  37. _, err := ParseArgs(args, &msg)
  38. if err != nil {
  39. return Fail(err)
  40. } else {
  41. fmt.Println(msg)
  42. }
  43. return None()
  44. }
  45. func p(vm *VM, args ...Value) []Value {
  46. for _, arg := range args {
  47. fmt.Printf("%v\n", arg)
  48. }
  49. return None()
  50. }
  51. func trace(vm *VM, args ...Value) []Value {
  52. var b bool = true
  53. fmt.Printf("command trace: %v\n", args)
  54. _, err := ParseArgs(args, &b)
  55. if err != nil {
  56. fmt.Printf("Error: %s\n", err.Error())
  57. return Fail(err)
  58. }
  59. fmt.Printf("command trace: bool: %v\n", b)
  60. if b {
  61. vm.Tracer = FmtTracer{}
  62. } else {
  63. vm.Tracer = nil
  64. }
  65. return Ok(BoolValue(b))
  66. }
  67. func sumi(vm *VM, args ...Value) []Value {
  68. slice, err := ParseArgsToIntSlice(args)
  69. if err != nil {
  70. fmt.Printf("Error: %s\n", err.Error())
  71. return Fail(err)
  72. }
  73. res := int(0)
  74. for _, val := range slice {
  75. res += val
  76. }
  77. return IntOk(res)
  78. }
  79. func sumf(vm *VM, args ...Value) []Value {
  80. slice, err := ParseArgsToFloat64Slice(args)
  81. if err != nil {
  82. fmt.Printf("Error: %s\n", err.Error())
  83. return Fail(err)
  84. }
  85. res := float64(0)
  86. for _, val := range slice {
  87. res += val
  88. }
  89. return FloatOk(res)
  90. }
  91. func addi(vm *VM, args ...Value) []Value {
  92. var v1, v2 int
  93. _, err := ParseArgs(args, &v1, &v2)
  94. if err != nil {
  95. return Fail(err)
  96. }
  97. return IntOk(v1 + v2)
  98. }
  99. func addf(vm *VM, args ...Value) []Value {
  100. var v1, v2 float64
  101. _, err := ParseArgs(args, &v1, &v2)
  102. if err != nil {
  103. return Fail(err)
  104. }
  105. return FloatOk(v1 + v2)
  106. }
  107. func subi(vm *VM, args ...Value) []Value {
  108. var v1, v2 int
  109. _, err := ParseArgs(args, &v1, &v2)
  110. if err != nil {
  111. return Fail(err)
  112. }
  113. return IntOk(v1 - v2)
  114. }
  115. func subf(vm *VM, args ...Value) []Value {
  116. var v1, v2 float64
  117. _, err := ParseArgs(args, &v1, &v2)
  118. if err != nil {
  119. return Fail(err)
  120. }
  121. return FloatOk(v1 - v2)
  122. }
  123. func muli(vm *VM, args ...Value) []Value {
  124. var v1, v2 int
  125. _, err := ParseArgs(args, &v1, &v2)
  126. if err != nil {
  127. return Fail(err)
  128. }
  129. return IntOk(v1 * v2)
  130. }
  131. func mulf(vm *VM, args ...Value) []Value {
  132. var v1, v2 float64
  133. _, err := ParseArgs(args, &v1, &v2)
  134. if err != nil {
  135. return Fail(err)
  136. }
  137. return FloatOk(v1 * v2)
  138. }
  139. func divi(vm *VM, args ...Value) []Value {
  140. var v1, v2 int
  141. _, err := ParseArgs(args, &v1, &v2)
  142. if err != nil {
  143. return Fail(err)
  144. }
  145. return IntOk(v1 / v2)
  146. }
  147. func divf(vm *VM, args ...Value) []Value {
  148. var v1, v2 float64
  149. _, err := ParseArgs(args, &v1, &v2)
  150. if err != nil {
  151. return Fail(err)
  152. }
  153. return FloatOk(v1 / v2)
  154. }
  155. func val(vm *VM, args ...Value) []Value {
  156. if len(args) < 1 {
  157. return []Value{NewErrorValuef("val requres at least one argument.")}
  158. }
  159. return args
  160. }
  161. func to(vm *VM, args ...Value) []Value {
  162. var name string
  163. rest, err := ParseArgs(args, &name)
  164. if err != nil {
  165. return Fail(err)
  166. }
  167. if len(rest) < 1 {
  168. return Fail(NewErrorValuef("Need at least 2 arguments: %v", args))
  169. }
  170. last := rest[len(rest)-1]
  171. block, isBlock := last.(*BlockValue)
  172. if ! isBlock {
  173. return Fail(NewErrorValuef("Not a block: %v", last))
  174. }
  175. param := rest[0:len(rest)-1]
  176. defpars := []*Parameter{}
  177. for i := 1 ; i < len(param) ; i += 2 {
  178. par := &Parameter{}
  179. name := param[i-1]
  180. typ := param[i]
  181. var ok bool
  182. if par.Name, ok = name.(WordValue); !ok {
  183. return Fail(NewErrorValuef("Not a word value: %v", name))
  184. }
  185. if par.Type, ok = typ.(TypeValue); !ok {
  186. return Fail(NewErrorValuef("Not a type value: %v", typ))
  187. }
  188. defpars = append(defpars, par)
  189. }
  190. return Ok(vm.RegisterDefined(name, defpars, block))
  191. }
  192. func cover(vm *VM, args ...Value) []Value {
  193. var name, target string
  194. rest, err := ParseArgs(args, &name, &target)
  195. if err != nil {
  196. return Fail(err)
  197. }
  198. types := []TypeValue{}
  199. for i, arg := range rest {
  200. if typ, ok := arg.(TypeValue) ; ok {
  201. types = append(types, typ)
  202. } else {
  203. return Fail(NewErrorValuef("Argument %d: not a type: %v %s", i+2, arg, arg.String()))
  204. }
  205. }
  206. err = vm.AddOverload(name, target, types...)
  207. if err != nil {
  208. return Fail(err)
  209. }
  210. return Ok()
  211. }
  212. func types(vm *VM, args ...Value) []Value {
  213. result := []Value{}
  214. for i, arg := range args {
  215. typ := arg.Type()
  216. result = append(result, typ)
  217. fmt.Printf("Type %d: %s\n", i, typ.String())
  218. }
  219. return Ok(NewListValue(result...))
  220. }
  221. func set(vm *VM, val ...Value) []Value {
  222. if len(val) < 2 {
  223. return Fail(fmt.Errorf("set needs at least 2 arguments: received %v", val))
  224. }
  225. target := val[0].String()
  226. value := val[1]
  227. if target == "(" || target == "$" {
  228. if len(val) < 3 {
  229. return Fail(fmt.Errorf("indirect get needs results: received %v", val))
  230. }
  231. target = val[1].String()
  232. value = val[2]
  233. }
  234. vm.Register(target, value)
  235. return Ok(value)
  236. }
  237. func get(vm *VM, val ...Value) []Value {
  238. if len(val) < 1 {
  239. return Fail(fmt.Errorf("get needs at least 1 argument"))
  240. }
  241. target := val[0].String()
  242. if target == "(" || target == "$" {
  243. if len(val) < 2 {
  244. return Fail(fmt.Errorf("indirect get needs results: received %v", val))
  245. }
  246. target = val[1].String()
  247. }
  248. return Ok(vm.Lookup(target))
  249. }
  250. func help(vm *VM, val ...Value) [] Value {
  251. if len(val) < 1 {
  252. fmt.Printf("help <callable> will display help on the callable\n\nThe following commands are available:\n")
  253. helpers := vm.DefinedHelpers()
  254. sort.SliceStable(helpers, func(i, j int) bool {
  255. return helpers[i].HelperName() < helpers[j].HelperName()
  256. })
  257. for _, helper := range helpers {
  258. fl := strings.SplitN(helper.Help(),"\n", 2)
  259. fmt.Printf("%s %s: \n", helper.HelperName(), fl[0])
  260. }
  261. return Ok()
  262. }
  263. targetName := val[0].String()
  264. target := vm.Lookup(targetName)
  265. if target == nil {
  266. fmt.Printf("help: %s not found.\n", targetName)
  267. }
  268. if helper, isHelper := target.(Helper) ; isHelper {
  269. help := helper.Help()
  270. fmt.Printf("%s: %s.\n", targetName, help)
  271. return Ok(StringValue(help))
  272. }
  273. return Ok()
  274. }
  275. func explain(vm *VM, val ...Value) [] Value {
  276. var target, help string
  277. _, err := ParseArgs(val, &target, &help)
  278. if err != nil {
  279. return Fail(err)
  280. }
  281. err = vm.SetHelp(target, help)
  282. if err != nil {
  283. return Fail(err)
  284. }
  285. return Ok(StringValue(help))
  286. }
  287. func exit(vm *VM, val ...Value) [] Value {
  288. var code int
  289. _, err := ParseArgs(val, &code)
  290. if err != nil {
  291. runtime.Goexit()
  292. }
  293. vm.ExitStatus = code
  294. runtime.Goexit()
  295. return Ok()
  296. }
  297. func (vm *VM) RegisterBuiltins() {
  298. vm.RegisterBuiltinWithHelp("addi", addi, `[Int Int] -> Int: adds two integers together`)
  299. vm.RegisterBuiltinWithHelp("addf", addf, `[Int Int] -> Int: adds two floats together`)
  300. vm.RegisterBuiltin("cover", cover)
  301. vm.RegisterBuiltin("sumi", sumi)
  302. vm.RegisterBuiltin("sumf", sumf)
  303. vm.RegisterBuiltin("subi", subi)
  304. vm.RegisterBuiltin("subf", subf)
  305. vm.RegisterBuiltin("divi", divi)
  306. vm.RegisterBuiltin("divf", divf)
  307. vm.RegisterBuiltin("muli", muli)
  308. vm.RegisterBuiltin("mulf", mulf)
  309. err := vm.AddOverload("mul", "mulf", FloatTypeValue, FloatTypeValue)
  310. if err != nil {
  311. fmt.Printf("Errror registering overload: %s", err)
  312. }
  313. err = vm.AddOverload("mul", "muli", IntTypeValue, IntTypeValue)
  314. if err != nil {
  315. fmt.Printf("Errror registering overload: %s", err)
  316. }
  317. err = vm.AddOverload("mul", "mulf", FloatTypeValue, IntTypeValue)
  318. if err != nil {
  319. fmt.Printf("Errror registering overload: %s", err)
  320. }
  321. err = vm.AddOverload("mul", "mulf", IntTypeValue, FloatTypeValue)
  322. if err != nil {
  323. fmt.Printf("Errror registering overload: %s", err)
  324. }
  325. // vm.RegisterCover("add")
  326. vm.RegisterBuiltin("p", p)
  327. vm.RegisterBuiltin("println", println)
  328. vm.RegisterBuiltin("printf", printf)
  329. vm.RegisterBuiltin("trace", trace)
  330. vm.RegisterBuiltin("to", to)
  331. vm.RegisterBuiltin("types", types)
  332. vm.RegisterBuiltin("val", val)
  333. vm.RegisterBuiltin("set", set)
  334. vm.RegisterBuiltin("get", get)
  335. vm.RegisterBuiltin("help", help)
  336. vm.RegisterBuiltin("explain", explain)
  337. vm.RegisterBuiltin("exit", exit)
  338. vm.SetHelp("mul", " Num: Multiplies two numbers. Cover for muli and mulf.")
  339. }