builtin.go 7.9 KB

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