PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/actions/denemo-modules/scheme.scm

#
Scheme | 339 lines | 256 code | 45 blank | 38 comment | 0 complexity | d4be6fe4b3d37f8d97f82128b7b21401 MD5 | raw file
Possible License(s): GPL-3.0
  1. (use-modules (srfi srfi-1)) ; List library
  2. ;; In this file are only functions that enhance the traditional Guile functions. Nothing depends on any Denemo functions nor on anything which is not in this file. There might be dependencies between each other though. Conclusion: This file can be run from guile without any errors about functions not found.
  3. ; Create a seed for (random int) one time Denemo starts. The seed is altered by random itself afterwards.
  4. (let ((time (gettimeofday)))
  5. (set! *random-state*
  6. (seed->random-state (+ (car time)
  7. (cdr time)))))
  8. ;Blank clears the console output. Don't use in released scripts, only for debugging.
  9. (define (Blank)
  10. (system "clear"))
  11. ;disp is an advanced display. Just give anything you want to print, it appends strings automatically and does a line break in the end. Don't use in released scripts, only for debugging.
  12. (define disp (lambda args
  13. (letrec ((disp-in (lambda (arg)
  14. (if (null? arg)
  15. #f
  16. (begin
  17. (display (car arg))
  18. (disp-in (cdr arg)))))))
  19. (disp-in args)
  20. (newline))))
  21. ;Doublequote constant to avoid backslashing
  22. (define DBLQ "\"")
  23. ;Linefeed constant to avoid backslashing
  24. (define LFEED "\n")
  25. ;Stop constant to avoid backslashing
  26. (define stop "\0")
  27. ; A function that returns #f for cases where commands work with chunks of code. this prevents the spamming of (lambda () #f) for a function that returns #f.
  28. (define (False)
  29. #f)
  30. ; A function that returns #t. See (False)
  31. (define (True)
  32. #t)
  33. ;repeat executes a proc n times
  34. (define (Repeat proc n)
  35. (let loop ((counter 0))
  36. (if (= n counter)
  37. #t
  38. (begin
  39. (proc)
  40. (loop (1+ counter))))))
  41. ;Repeat a command until it returns #f
  42. ;Warning: Functions that do not return #f create infinity loops!
  43. (define (RepeatUntilFail proc)
  44. (let loop ()
  45. (if (proc)
  46. (loop)
  47. #f)))
  48. ;Repeat a function while another (a test) returns #t. The return value of proc does NOT matter
  49. ;;Warning: From all Repeat functions this one has the highest probability to be stuck in a loop forever. Always use tests that MUST return #f in the end. Do NOT use the Denemo tests like (None?) or (Music?) for example, they know nothing about a staffs end.
  50. (define (RepeatProcWhileTest proc test)
  51. (RepeatUntilFail
  52. (lambda ()
  53. (if (test)
  54. (begin (proc) #t); this is a dumb script. It will try to execute proc again even if proc itself returned #f.
  55. #f )))) ; test failed, let RepeatUntilFail fail.
  56. ;Replace a part of a string
  57. (define (Replace-nth list n elem)
  58. (cond
  59. ((null? list) ())
  60. ((eq? n 0) (cons elem (cdr list)))
  61. (#t (cons(car list) (replace-nth (cdr list) (- n 1) elem)))))
  62. ; String Escaper
  63. ;; Escapes Strings
  64. ;; from brlewis http://srfi.schemers.org/srfi-13/mail-archive/msg00025.html
  65. (define (string-escaper esc)
  66. (let ((spec (char-escape-spec esc)))
  67. (lambda (str) (string-escape str spec))))
  68. (define (string-needs-escape? str esc)
  69. (let ((len (string-length str)))
  70. (let loop ((i 0))
  71. (if (= i len)
  72. #f
  73. (let ((c (string-ref str i)))
  74. (if (and (char>=? c (car esc))
  75. (char<=? c (cadr esc)))
  76. #t
  77. (loop (+ 1 i))))))))
  78. (define (string-escape str esc)
  79. (if (string-needs-escape? str esc)
  80. (list->string
  81. (reverse
  82. (let ((len (string-length str)))
  83. (let loop ((i 0)
  84. (li '()))
  85. (if (= i len)
  86. li
  87. (loop (+ 1 i)
  88. (let ((c (string-ref str i)))
  89. (if (and (char>=? c (car esc))
  90. (char<=? c (cadr esc)))
  91. (let ((li2 (vector-ref
  92. (caddr esc)
  93. (- (char->integer c)
  94. (char->integer (car esc))))))
  95. (if li2
  96. (append li2 li)
  97. (cons c li)))
  98. (cons c li)))))))))
  99. str))
  100. (define (char-escape-spec speclist)
  101. (let ((minchar (caar speclist))
  102. (maxchar (caar speclist)))
  103. (let loop ((li (cdr speclist)))
  104. (if (not (null? li))
  105. (begin
  106. (let ((testchar (caar li)))
  107. (if (char<? testchar minchar)
  108. (set! minchar testchar))
  109. (if (char>? testchar maxchar)
  110. (set! maxchar testchar)))
  111. (loop (cdr li)))))
  112. (list
  113. minchar
  114. maxchar
  115. (let ((specv (make-vector (+ 1 (- (char->integer maxchar)
  116. (char->integer minchar))) #f)))
  117. (map (lambda (specpair)
  118. (vector-set! specv
  119. (- (char->integer (car specpair))
  120. (char->integer minchar))
  121. (reverse (string->list (cdr specpair)))))
  122. speclist)
  123. specv))))
  124. ;; examples of use
  125. (define html-escape (string-escaper '((#\< . "&lt;")
  126. (#\> . "&gt;")
  127. (#\& . "&amp;"))))
  128. (define scheme-escape (string-escaper '((#\\ . "\\\\")
  129. (#\" . "\\\""))))
  130. #! (define latex-escape (string-escaper '((#\\ . "\\\\")
  131. (#\~ . "\\~")
  132. (#\# . "\\#")
  133. (#\$ . "\\$")
  134. (#\% . "\\%")
  135. (#\^ . "\\^")
  136. (#\& . "\\&")
  137. (#\{ . "\\{")
  138. (#\} . "\\}")
  139. (#\_ . "\\_")))) !#
  140. ;;;;;;;;;; Parse strings for json values
  141. (define (ParseJson target key)
  142. (let ((theregexp #f) (thematch #f))
  143. ;;; this is the regexp to find "key":"something" with the something being the match, ie in ()
  144. (set! theregexp (string-append "\"" key "\":\"([^\"]*)\""))
  145. ;;;;; this gets a match structure for target, so if there is a match
  146. (set! thematch (string-match theregexp target))
  147. (if (regexp-match? thematch) ;;; if there was a match return it
  148. (match:substring thematch 1)
  149. ;;;if there was no match return #f
  150. #f)))
  151. ; Shuffling Sequences
  152. ;;; http://mumble.net/~campbell/scheme/shuffle.scm
  153. ;;; This code is written by Taylor R. Campbell and placed in the Public
  154. ;;; Domain. All warranties are disclaimed.
  155. ;;; This uses SRFIs 1 (list-lib) and 8 (receive).
  156. (use-modules (srfi srfi-1)) ; List library
  157. (use-modules (srfi srfi-8)) ; Returning and Accepting Multiple Values
  158. ;;;; Merge Shuffle
  159. ;;; Partition the list into two equal halves; shuffle the two halves,
  160. ;;; and then merge them by randomly choosing which half to select the
  161. ;;; next element from.
  162. (define (Flip-coin)
  163. (if (= 1 (random 2))
  164. #t
  165. #f))
  166. (define (Merge-shuffle-list list)
  167. (define (merge a b)
  168. (cond ((not (pair? a)) b)
  169. ((not (pair? b)) a)
  170. (else
  171. (if (Flip-coin)
  172. (cons (car a) (merge (cdr a) b))
  173. (cons (car b) (merge a (cdr b)))))))
  174. (define (partition list a b)
  175. (let ((next (cdr list))
  176. (a b)
  177. (b (cons (car list) a)))
  178. (if (null-list? next)
  179. (values a b)
  180. (partition next a b))))
  181. (if (null-list? list)
  182. '()
  183. (let shuffle ((list list))
  184. (if (null-list? (cdr list))
  185. list
  186. (receive (a b) (partition list '() '())
  187. (merge (shuffle a) (shuffle b)))))))
  188. ;;; This has *far* too many SET-CDR!s.
  189. (define (Merge-shuffle-list! list)
  190. (define (merge! a b)
  191. (cond ((null-list? a) b)
  192. ((null-list? b) a)
  193. ((Flip-coin) (%merge! a b) a)
  194. (else (%merge! b a) b)))
  195. (define (%merge! a b)
  196. (cond ((null-list? (cdr a))
  197. (set-cdr! a b))
  198. ((Flip-coin)
  199. (%merge! (cdr a) b))
  200. (else
  201. (%merge! b (let ((next (cdr a)))
  202. (set-cdr! a b)
  203. next)))))
  204. (define (partition! list a b)
  205. (let ((next (cdr list)))
  206. (set-cdr! list a)
  207. (if (null-list? next)
  208. (values list b)
  209. (partition! next b list))))
  210. (if (null-list? list)
  211. '()
  212. (let shuffle! ((list list))
  213. (if (null-list? (cdr list))
  214. list
  215. (receive (a b) (partition! list '() '())
  216. (merge! (shuffle! a) (shuffle! b)))))))
  217. ;; End Shuffle
  218. ; from http://icem.folkwang-hochschule.de/~finnendahl/cm_kurse/doc/t-y-scheme/t-y-scheme-Z-H-7.html
  219. ;; needed for define-macro defstruct
  220. (define list-position
  221. (lambda (o l)
  222. (let loop ((i 0) (l l))
  223. (if (null? l) #f
  224. (if (eqv? (car l) o) i
  225. (loop (+ i 1) (cdr l)))))))
  226. ; from http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-11.html#node_sec_9.2
  227. (define-macro defstruct
  228. (lambda (s . ff)
  229. (let ((s-s (symbol->string s)) (n (length ff)))
  230. (let* ((n+1 (+ n 1))
  231. (vv (make-vector n+1)))
  232. (let loop ((i 1) (ff ff))
  233. (if (<= i n)
  234. (let ((f (car ff)))
  235. (vector-set! vv i
  236. (if (pair? f) (cadr f) '(if #f #f)))
  237. (loop (+ i 1) (cdr ff)))))
  238. (let ((ff (map (lambda (f) (if (pair? f) (car f) f))
  239. ff)))
  240. `(begin
  241. (define ,(string->symbol
  242. (string-append "make-" s-s))
  243. (lambda fvfv
  244. (let ((st (make-vector ,n+1)) (ff ',ff))
  245. (vector-set! st 0 ',s)
  246. ,@(let loop ((i 1) (r '()))
  247. (if (>= i n+1) r
  248. (loop (+ i 1)
  249. (cons `(vector-set! st ,i
  250. ,(vector-ref vv i))
  251. r))))
  252. (let loop ((fvfv fvfv))
  253. (if (not (null? fvfv))
  254. (begin
  255. (vector-set! st
  256. (+ (list-position (car fvfv) ff)
  257. 1)
  258. (cadr fvfv))
  259. (loop (cddr fvfv)))))
  260. st)))
  261. ,@(let loop ((i 1) (procs '()))
  262. (if (>= i n+1) procs
  263. (loop (+ i 1)
  264. (let ((f (symbol->string
  265. (list-ref ff (- i 1)))))
  266. (cons
  267. `(define ,(string->symbol
  268. (string-append
  269. s-s "." f))
  270. (lambda (x) (vector-ref x ,i)))
  271. (cons
  272. `(define ,(string->symbol
  273. (string-append
  274. "set!" s-s "." f))
  275. (lambda (x v)
  276. (vector-set! x ,i v)))
  277. procs))))))
  278. (define ,(string->symbol (string-append s-s "?"))
  279. (lambda (x)
  280. (and (vector? x)
  281. (eqv? (vector-ref x 0) ',s))))))))))
  282. ;InvertedMap takes a list of functions and applies each to a single value and returns a list of returnvalues.
  283. (define (InvertedMap val . funcs)
  284. (concatenate
  285. (map (lambda (proc) (call-with-values (lambda () (proc val)) list))
  286. funcs)))
  287. #! (define (InvertedMap2 value . functions)
  288. (define returnlist (list #f))
  289. (for-each (lambda (x)
  290. (define return (x value))
  291. (if return
  292. (append! returnlist (list return))))
  293. functions)
  294. (list-tail returnlist 1)) !#