functions.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. package glisp
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "os"
  7. )
  8. var WrongNargs error = errors.New("wrong number of arguments")
  9. type GlispFunction []Instruction
  10. type GlispUserFunction func(*Glisp, string, []Sexp) (Sexp, error)
  11. func CompareFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  12. if len(args) != 2 {
  13. return SexpNull, WrongNargs
  14. }
  15. res, err := Compare(args[0], args[1])
  16. if err != nil {
  17. return SexpNull, err
  18. }
  19. cond := false
  20. switch name {
  21. case "<":
  22. cond = res < 0
  23. case ">":
  24. cond = res > 0
  25. case "<=":
  26. cond = res <= 0
  27. case ">=":
  28. cond = res >= 0
  29. case "=":
  30. cond = res == 0
  31. case "not=":
  32. cond = res != 0
  33. }
  34. return SexpBool(cond), nil
  35. }
  36. func BinaryIntFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  37. if len(args) != 2 {
  38. return SexpNull, WrongNargs
  39. }
  40. var op IntegerOp
  41. switch name {
  42. case "sll":
  43. op = ShiftLeft
  44. case "sra":
  45. op = ShiftRightArith
  46. case "srl":
  47. op = ShiftRightLog
  48. case "mod":
  49. op = Modulo
  50. }
  51. return IntegerDo(op, args[0], args[1])
  52. }
  53. func BitwiseFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  54. if len(args) != 2 {
  55. return SexpNull, WrongNargs
  56. }
  57. var op IntegerOp
  58. switch name {
  59. case "bit-and":
  60. op = BitAnd
  61. case "bit-or":
  62. op = BitOr
  63. case "bit-xor":
  64. op = BitXor
  65. }
  66. accum := args[0]
  67. var err error
  68. for _, expr := range args[1:] {
  69. accum, err = IntegerDo(op, accum, expr)
  70. if err != nil {
  71. return SexpNull, err
  72. }
  73. }
  74. return accum, nil
  75. }
  76. func ComplementFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  77. if len(args) != 1 {
  78. return SexpNull, WrongNargs
  79. }
  80. switch t := args[0].(type) {
  81. case SexpInt:
  82. return ^t, nil
  83. case SexpChar:
  84. return ^t, nil
  85. }
  86. return SexpNull, errors.New("Argument to bit-not should be integer")
  87. }
  88. func NumericFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  89. if len(args) < 1 {
  90. return SexpNull, WrongNargs
  91. }
  92. var err error
  93. accum := args[0]
  94. var op NumericOp
  95. switch name {
  96. case "+":
  97. op = Add
  98. case "-":
  99. op = Sub
  100. case "*":
  101. op = Mult
  102. case "/":
  103. op = Div
  104. }
  105. for _, expr := range args[1:] {
  106. accum, err = NumericDo(op, accum, expr)
  107. if err != nil {
  108. return SexpNull, err
  109. }
  110. }
  111. return accum, nil
  112. }
  113. func ConsFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  114. if len(args) != 2 {
  115. return SexpNull, WrongNargs
  116. }
  117. return Cons(args[0], args[1]), nil
  118. }
  119. func FirstFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  120. if len(args) != 1 {
  121. return SexpNull, WrongNargs
  122. }
  123. switch expr := args[0].(type) {
  124. case SexpPair:
  125. return expr.head, nil
  126. case SexpArray:
  127. return expr[0], nil
  128. }
  129. return SexpNull, WrongType
  130. }
  131. func RestFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  132. if len(args) != 1 {
  133. return SexpNull, WrongNargs
  134. }
  135. switch expr := args[0].(type) {
  136. case SexpPair:
  137. return expr.tail, nil
  138. case SexpArray:
  139. if len(expr) == 0 {
  140. return expr, nil
  141. }
  142. return expr[1:], nil
  143. case SexpSentinel:
  144. if expr == SexpNull {
  145. return SexpNull, nil
  146. }
  147. }
  148. return SexpNull, WrongType
  149. }
  150. func ArrayAccessFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  151. if len(args) < 2 {
  152. return SexpNull, WrongNargs
  153. }
  154. var arr SexpArray
  155. switch t := args[0].(type) {
  156. case SexpArray:
  157. arr = t
  158. default:
  159. return SexpNull, errors.New("First argument of aget must be array")
  160. }
  161. var i int
  162. switch t := args[1].(type) {
  163. case SexpInt:
  164. i = int(t)
  165. case SexpChar:
  166. i = int(t)
  167. default:
  168. return SexpNull, errors.New("Second argument of aget must be integer")
  169. }
  170. if i < 0 || i >= len(arr) {
  171. return SexpNull, errors.New("Array index out of bounds")
  172. }
  173. if name == "aget" {
  174. return arr[i], nil
  175. }
  176. if len(args) != 3 {
  177. return SexpNull, WrongNargs
  178. }
  179. arr[i] = args[2]
  180. return SexpNull, nil
  181. }
  182. func SgetFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  183. if len(args) != 2 {
  184. return SexpNull, WrongNargs
  185. }
  186. var str SexpStr
  187. switch t := args[0].(type) {
  188. case SexpStr:
  189. str = t
  190. default:
  191. return SexpNull, errors.New("First argument of sget must be string")
  192. }
  193. var i int
  194. switch t := args[1].(type) {
  195. case SexpInt:
  196. i = int(t)
  197. case SexpChar:
  198. i = int(t)
  199. default:
  200. return SexpNull, errors.New("Second argument of sget must be integer")
  201. }
  202. return SexpChar(str[i]), nil
  203. }
  204. func HashAccessFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  205. if len(args) < 2 || len(args) > 3 {
  206. return SexpNull, WrongNargs
  207. }
  208. var hash SexpHash
  209. switch e := args[0].(type) {
  210. case SexpHash:
  211. hash = e
  212. default:
  213. return SexpNull, errors.New("first argument of hget must be hash")
  214. }
  215. switch name {
  216. case "hget":
  217. if len(args) == 3 {
  218. return hash.HashGetDefault(args[1], args[2])
  219. }
  220. return hash.HashGet(args[1])
  221. case "hset!":
  222. err := hash.HashSet(args[1], args[2])
  223. return SexpNull, err
  224. case "hdel!":
  225. if len(args) != 2 {
  226. return SexpNull, WrongNargs
  227. }
  228. err := hash.HashDelete(args[1])
  229. return SexpNull, err
  230. }
  231. return SexpNull, nil
  232. }
  233. func SliceFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  234. if len(args) != 3 {
  235. return SexpNull, WrongNargs
  236. }
  237. var start int
  238. var end int
  239. switch t := args[1].(type) {
  240. case SexpInt:
  241. start = int(t)
  242. case SexpChar:
  243. start = int(t)
  244. default:
  245. return SexpNull, errors.New("Second argument of slice must be integer")
  246. }
  247. switch t := args[2].(type) {
  248. case SexpInt:
  249. end = int(t)
  250. case SexpChar:
  251. end = int(t)
  252. default:
  253. return SexpNull, errors.New("Third argument of slice must be integer")
  254. }
  255. switch t := args[0].(type) {
  256. case SexpArray:
  257. return SexpArray(t[start:end]), nil
  258. case SexpStr:
  259. return SexpStr(t[start:end]), nil
  260. }
  261. return SexpNull, errors.New("First argument of slice must be array or string")
  262. }
  263. func LenFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  264. if len(args) != 1 {
  265. return SexpNull, WrongNargs
  266. }
  267. switch t := args[0].(type) {
  268. case SexpArray:
  269. return SexpInt(len(t)), nil
  270. case SexpStr:
  271. return SexpInt(len(t)), nil
  272. case SexpHash:
  273. return SexpInt(HashCountKeys(t)), nil
  274. }
  275. return SexpInt(0), errors.New("argument must be string or array")
  276. }
  277. func AppendFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  278. if len(args) != 2 {
  279. return SexpNull, WrongNargs
  280. }
  281. switch t := args[0].(type) {
  282. case SexpArray:
  283. return SexpArray(append(t, args[1])), nil
  284. case SexpStr:
  285. return AppendStr(t, args[1])
  286. }
  287. return SexpNull, errors.New("First argument of append must be array or string")
  288. }
  289. func ConcatFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  290. if len(args) != 2 {
  291. return SexpNull, WrongNargs
  292. }
  293. switch t := args[0].(type) {
  294. case SexpArray:
  295. return ConcatArray(t, args[1])
  296. case SexpStr:
  297. return ConcatStr(t, args[1])
  298. case SexpPair:
  299. return ConcatList(t, args[1])
  300. }
  301. return SexpNull, errors.New("expected strings or arrays")
  302. }
  303. func ReadFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  304. if len(args) != 1 {
  305. return SexpNull, WrongNargs
  306. }
  307. str := ""
  308. switch t := args[0].(type) {
  309. case SexpStr:
  310. str = string(t)
  311. default:
  312. return SexpNull, WrongType
  313. }
  314. lexer := NewLexerFromStream(bytes.NewBuffer([]byte(str)))
  315. parser := Parser{lexer, env}
  316. return ParseExpression(&parser)
  317. }
  318. func EvalFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  319. if len(args) != 1 {
  320. return SexpNull, WrongNargs
  321. }
  322. newenv := env.Duplicate()
  323. err := newenv.LoadExpressions(args)
  324. if err != nil {
  325. return SexpNull, errors.New("failed to compile expression")
  326. }
  327. newenv.pc = 0
  328. return newenv.Run()
  329. }
  330. func TypeQueryFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  331. if len(args) != 1 {
  332. return SexpNull, WrongNargs
  333. }
  334. var result bool
  335. switch name {
  336. case "list?":
  337. result = IsList(args[0])
  338. case "null?":
  339. result = (args[0] == SexpNull)
  340. case "array?":
  341. result = IsArray(args[0])
  342. case "number?":
  343. result = IsNumber(args[0])
  344. case "float?":
  345. result = IsFloat(args[0])
  346. case "int?":
  347. result = IsInt(args[0])
  348. case "char?":
  349. result = IsChar(args[0])
  350. case "symbol?":
  351. result = IsSymbol(args[0])
  352. case "string?":
  353. result = IsString(args[0])
  354. case "hash?":
  355. result = IsHash(args[0])
  356. case "zero?":
  357. result = IsZero(args[0])
  358. case "empty?":
  359. result = IsEmpty(args[0])
  360. }
  361. return SexpBool(result), nil
  362. }
  363. func PrintFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  364. if len(args) != 1 {
  365. return SexpNull, WrongNargs
  366. }
  367. var str string
  368. switch expr := args[0].(type) {
  369. case SexpStr:
  370. str = string(expr)
  371. default:
  372. str = expr.SexpString()
  373. }
  374. switch name {
  375. case "println":
  376. fmt.Println(str)
  377. case "print":
  378. fmt.Print(str)
  379. }
  380. return SexpNull, nil
  381. }
  382. func NotFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  383. if len(args) != 1 {
  384. return SexpNull, WrongNargs
  385. }
  386. result := SexpBool(!IsTruthy(args[0]))
  387. return result, nil
  388. }
  389. func ApplyFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  390. if len(args) != 2 {
  391. return SexpNull, WrongNargs
  392. }
  393. var fun SexpFunction
  394. var funargs SexpArray
  395. switch e := args[0].(type) {
  396. case SexpFunction:
  397. fun = e
  398. default:
  399. return SexpNull, errors.New("first argument must be function")
  400. }
  401. switch e := args[1].(type) {
  402. case SexpArray:
  403. funargs = e
  404. case SexpPair:
  405. var err error
  406. funargs, err = ListToArray(e)
  407. if err != nil {
  408. return SexpNull, err
  409. }
  410. default:
  411. return SexpNull, errors.New("second argument must be array or list")
  412. }
  413. return env.Apply(fun, funargs)
  414. }
  415. func MapFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  416. if len(args) != 2 {
  417. return SexpNull, WrongNargs
  418. }
  419. var fun SexpFunction
  420. switch e := args[0].(type) {
  421. case SexpFunction:
  422. fun = e
  423. default:
  424. return SexpNull, errors.New(fmt.Sprint("first argument must be function had", fmt.Sprintf("%T", e), " ", e))
  425. }
  426. switch e := args[1].(type) {
  427. case SexpArray:
  428. return MapArray(env, fun, e)
  429. case SexpPair:
  430. return MapList(env, fun, e)
  431. }
  432. return SexpNull, errors.New("second argument must be array")
  433. }
  434. func MakeArrayFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  435. if len(args) < 1 {
  436. return SexpNull, WrongNargs
  437. }
  438. var size int
  439. switch e := args[0].(type) {
  440. case SexpInt:
  441. size = int(e)
  442. default:
  443. return SexpNull, errors.New("first argument must be integer")
  444. }
  445. var fill Sexp
  446. if len(args) == 2 {
  447. fill = args[1]
  448. } else {
  449. fill = SexpNull
  450. }
  451. arr := make([]Sexp, size)
  452. for i := range arr {
  453. arr[i] = fill
  454. }
  455. return SexpArray(arr), nil
  456. }
  457. func ConstructorFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  458. switch name {
  459. case "array":
  460. return SexpArray(args), nil
  461. case "list":
  462. return MakeList(args), nil
  463. case "hash":
  464. return MakeHash(args, "hash")
  465. }
  466. return SexpNull, errors.New("invalid constructor")
  467. }
  468. func SymnumFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  469. if len(args) != 1 {
  470. return SexpNull, WrongNargs
  471. }
  472. switch t := args[0].(type) {
  473. case SexpSymbol:
  474. return SexpInt(t.number), nil
  475. }
  476. return SexpNull, errors.New("argument must be symbol")
  477. }
  478. func SourceFileFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  479. if len(args) < 1 {
  480. return SexpNull, WrongNargs
  481. }
  482. var sourceItem func(item Sexp) error
  483. sourceItem = func(item Sexp) error {
  484. switch t := item.(type) {
  485. case SexpArray:
  486. for _, v := range t {
  487. if err := sourceItem(v); err != nil {
  488. return err
  489. }
  490. }
  491. case SexpPair:
  492. expr := item
  493. for expr != SexpNull {
  494. list := expr.(SexpPair)
  495. if err := sourceItem(list.head); err != nil {
  496. return err
  497. }
  498. expr = list.tail
  499. }
  500. case SexpStr:
  501. var f *os.File
  502. var err error
  503. if f, err = os.Open(string(t)); err != nil {
  504. return err
  505. }
  506. if err = env.SourceFile(f); err != nil {
  507. return err
  508. }
  509. f.Close()
  510. default:
  511. return fmt.Errorf("%v: Expected `string`, `list`, `array` given type %T val %v", name, item, item)
  512. }
  513. return nil
  514. }
  515. for _, v := range args {
  516. if err := sourceItem(v); err != nil {
  517. return SexpNull, err
  518. }
  519. }
  520. return SexpNull, nil
  521. }
  522. var MissingFunction = SexpFunction{"__missing", true, 0, false, nil, nil, nil}
  523. func MakeFunction(name string, nargs int, varargs bool,
  524. fun GlispFunction) SexpFunction {
  525. var sfun SexpFunction
  526. sfun.name = name
  527. sfun.user = false
  528. sfun.nargs = nargs
  529. sfun.varargs = varargs
  530. sfun.fun = fun
  531. return sfun
  532. }
  533. func MakeUserFunction(name string, ufun GlispUserFunction) SexpFunction {
  534. var sfun SexpFunction
  535. sfun.name = name
  536. sfun.user = true
  537. sfun.userfun = ufun
  538. return sfun
  539. }
  540. var BuiltinFunctions = map[string]GlispUserFunction{
  541. "<": CompareFunction,
  542. ">": CompareFunction,
  543. "<=": CompareFunction,
  544. ">=": CompareFunction,
  545. "=": CompareFunction,
  546. "not=": CompareFunction,
  547. "sll": BinaryIntFunction,
  548. "sra": BinaryIntFunction,
  549. "srl": BinaryIntFunction,
  550. "mod": BinaryIntFunction,
  551. "+": NumericFunction,
  552. "-": NumericFunction,
  553. "*": NumericFunction,
  554. "/": NumericFunction,
  555. "bit-and": BitwiseFunction,
  556. "bit-or": BitwiseFunction,
  557. "bit-xor": BitwiseFunction,
  558. "bit-not": ComplementFunction,
  559. "read": ReadFunction,
  560. "cons": ConsFunction,
  561. "first": FirstFunction,
  562. "rest": RestFunction,
  563. "car": FirstFunction,
  564. "cdr": RestFunction,
  565. "list?": TypeQueryFunction,
  566. "null?": TypeQueryFunction,
  567. "array?": TypeQueryFunction,
  568. "hash?": TypeQueryFunction,
  569. "number?": TypeQueryFunction,
  570. "int?": TypeQueryFunction,
  571. "float?": TypeQueryFunction,
  572. "char?": TypeQueryFunction,
  573. "symbol?": TypeQueryFunction,
  574. "string?": TypeQueryFunction,
  575. "zero?": TypeQueryFunction,
  576. "empty?": TypeQueryFunction,
  577. "println": PrintFunction,
  578. "print": PrintFunction,
  579. "not": NotFunction,
  580. "apply": ApplyFunction,
  581. "map": MapFunction,
  582. "make-array": MakeArrayFunction,
  583. "aget": ArrayAccessFunction,
  584. "aset!": ArrayAccessFunction,
  585. "sget": SgetFunction,
  586. "hget": HashAccessFunction,
  587. "hset!": HashAccessFunction,
  588. "hdel!": HashAccessFunction,
  589. "slice": SliceFunction,
  590. "len": LenFunction,
  591. "append": AppendFunction,
  592. "concat": ConcatFunction,
  593. "array": ConstructorFunction,
  594. "list": ConstructorFunction,
  595. "hash": ConstructorFunction,
  596. "symnum": SymnumFunction,
  597. "str": StringifyFunction,
  598. }
  599. func StringifyFunction(env *Glisp, name string, args []Sexp) (Sexp, error) {
  600. if len(args) != 1 {
  601. return SexpNull, WrongNargs
  602. }
  603. return SexpStr(args[0].SexpString()), nil
  604. }