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

/src/collects/moby/runtime/error-struct-to-dom.ss

http://github.com/bootstrapworld/wescheme-compiler2012
Scheme | 675 lines | 545 code | 99 blank | 31 comment | 0 complexity | 92bd991ad7019079f1bd2dbda73730e1 MD5 | raw file
  1. #lang s-exp "../../../private/restricted-runtime-scheme.ss"
  2. (require "arity-struct.ss")
  3. (require "error-struct.ss")
  4. (require "stx.ss")
  5. (require "scheme-value-to-dom.ss")
  6. (require "dom-helpers.ss")
  7. (require "dom-parameters.ss")
  8. ;; Error structure to dom code.
  9. ;; These functions produce DOMs out of the values in error-struct,
  10. ;; ready to be styled.
  11. (define (loc->jsexpr a-loc)
  12. (make-hash `((offset . ,(number->string (Loc-offset a-loc)))
  13. (line . ,(number->string (Loc-line a-loc)))
  14. (column . ,(number->string (Loc-column a-loc)))
  15. (span . ,(number->string (Loc-span a-loc)))
  16. (id . ,(Loc-id a-loc)))))
  17. (define (error-struct->jsexpr an-error)
  18. (define error-type (moby-error-error-type an-error))
  19. (cond
  20. [(Message? error-type)
  21. (let loop ([parts (Message-parts error-type)])
  22. (apply append (map (lambda (part)
  23. (cond
  24. [(list? part)
  25. (apply append (map loop part))]
  26. [(string? part)
  27. (list part)]
  28. [(ColoredPart? part)
  29. (list (make-hash `((type . "ColoredPart")
  30. (text . ,(ColoredPart-text part))
  31. (loc . ,(loc->jsexpr (ColoredPart-loc part))))))]
  32. [(GradientPart? part)
  33. (list (make-hash `((type . "GradientPart")
  34. (parts . ,(map loop (GradientPart-parts part))))))]
  35. [(MultiPart? part)
  36. (list (make-hash `((type . "MultiPart")
  37. (text . ,(MultiPart-text part))
  38. (locs . ,(map loc->jsexpr (MultiPart-locs part)))
  39. (solid . ,(MultiPart-solid part)))))]))
  40. parts)))]
  41. [else
  42. #f]))
  43. ;; error-struct-to-dom-sexp: dom (dom-parameters | false) -> sexp
  44. ;; Convert an error structure to a dom-sexp. Optionally provide a dom-parameters
  45. ;; that defines custom dom converters.
  46. (define (error-struct->dom-sexp an-error maybe-dom-parameters)
  47. (local [(define embedded-location (moby-error-location an-error))
  48. (define error-type (moby-error-error-type an-error))
  49. (define (add-toplevel-dom-error-wrapper a-dom)
  50. `(span ((class "Error"))
  51. ,a-dom
  52. (br () "")
  53. (span ((class "Error.location"))
  54. ,(Loc->dom-sexp embedded-location))))]
  55. (add-toplevel-dom-error-wrapper
  56. (cond
  57. [(Message? error-type)
  58. `(span ((class "Message"))
  59. ,@(let loop ([parts (Message-parts error-type)])
  60. (apply append (map (lambda (part)
  61. (cond
  62. [(list? part)
  63. (apply append (map loop part))]
  64. [(string? part)
  65. (list part)]
  66. [(ColoredPart? part)
  67. (list (ColoredPart-text part))]
  68. [(GradientPart? part)
  69. (apply append (map loop (GradientPart-parts part)))]
  70. [(MultiPart? part)
  71. (list (MultiPart-text part))]))
  72. parts))))]
  73. [(moby-error-type:unclosed-lexical-token? error-type)
  74. `(span ((class "Error-UnclosedLexicalToken"))
  75. (span ((class "Error.reason"))
  76. "Found "
  77. ,(scheme-value->dom-sexp (moby-error-type:unclosed-lexical-token-opener error-type)
  78. maybe-dom-parameters)
  79. " to start a "
  80. ,(moby-error-type:unclosed-lexical-token-type error-type)
  81. ", but no "
  82. ,(scheme-value->dom-sexp (moby-error-type:unclosed-lexical-token-closer error-type)
  83. maybe-dom-parameters)
  84. " to close it.")
  85. (span ((class "Error-UnclosedLexicalToken.type")
  86. (style "display:none"))
  87. ,(moby-error-type:unclosed-lexical-token-type error-type))
  88. (span ((class "Error-UnclosedLexicalToken.opener")
  89. (style "display:none"))
  90. ,(symbol->string (moby-error-type:unclosed-lexical-token-opener error-type)))
  91. (span ((class "Error-UnclosedLexicalToken.closer")
  92. (style "display:none"))
  93. ,(symbol->string (moby-error-type:unclosed-lexical-token-closer error-type))))]
  94. [(moby-error-type:unrecognized-lexical-token? error-type)
  95. `(span ((class "Error-UnrecognizedLexicalToken"))
  96. (span ((class "Error.reason"))
  97. "Found "
  98. ,(scheme-value->dom-sexp (moby-error-type:unrecognized-lexical-token-token error-type)
  99. maybe-dom-parameters)
  100. " which is not recognized as a program element.")
  101. (span ((class "Error-UnrecognizedLexicalToken.token")
  102. (style "display:none"))
  103. ,(symbol->string (moby-error-type:unrecognized-lexical-token-token error-type))))]
  104. [(moby-error-type:unsupported-lexical-token? error-type)
  105. `(span ((class "Error-UnsupportedLexicalToken"))
  106. (span ((class "Error.reason"))
  107. ,(scheme-value->dom-sexp (moby-error-type:unsupported-lexical-token-token error-type)
  108. maybe-dom-parameters)
  109. " is currently not supported.")
  110. (span ((class "Error-UnsupportedLexicalToken.token")
  111. (style "display:none"))
  112. ,(symbol->string (moby-error-type:unsupported-lexical-token-token error-type))))]
  113. [(moby-error-type:unsupported-expression-form? error-type)
  114. `(span ((class "Error-UnsupportedExpressionForm"))
  115. (span ((class "Error.reason"))
  116. ,(stx->dom-sexp (moby-error-type:unsupported-expression-form-expr error-type)
  117. maybe-dom-parameters)
  118. " is currently not supported.")
  119. (span ((class "Error-UnsupportedExpressionForm.expr")
  120. (style "display:none"))
  121. ,(stx->dom-sexp (moby-error-type:unsupported-expression-form-expr error-type)
  122. maybe-dom-parameters)))]
  123. ;;fixme: is this ever called?
  124. [(moby-error-type:unclosed-parentheses? error-type)
  125. `(span ((class "Error-UnclosedParentheses"))
  126. (span ((class "Error.reason"))
  127. "Found "
  128. ,(scheme-value->dom-sexp (moby-error-type:unclosed-parentheses-opener error-type)
  129. maybe-dom-parameters)
  130. " to start an expression, but no "
  131. ,(scheme-value->dom-sexp (moby-error-type:unclosed-parentheses-closer error-type)
  132. maybe-dom-parameters)
  133. " to close it.")
  134. (span ((class "Error-UnclosedParentheses.opener")
  135. (style "display:none"))
  136. ,(symbol->string (moby-error-type:unclosed-parentheses-opener error-type)))
  137. (span ((class "Error-UnclosedParentheses.closer")
  138. (style "display:none"))
  139. ,(symbol->string (moby-error-type:unclosed-parentheses-closer error-type))))]
  140. ;;fixme: is this ever called?
  141. [(moby-error-type:unbalanced-parentheses? error-type)
  142. `(span ((class "Error-UnbalancedParentheses"))
  143. "Found "
  144. ,(scheme-value->dom-sexp
  145. (moby-error-type:unbalanced-parentheses-opener error-type)
  146. maybe-dom-parameters)
  147. " earlier, and expected it to be matched with "
  148. ,(scheme-value->dom-sexp
  149. (moby-error-type:unbalanced-parentheses-closer error-type)
  150. maybe-dom-parameters)
  151. ", but instead found "
  152. ,(scheme-value->dom-sexp
  153. (moby-error-type:unbalanced-parentheses-observed error-type)
  154. maybe-dom-parameters)
  155. ".")]
  156. [(moby-error-type:syntax-not-applied? error-type)
  157. `(span ((class "Error-SyntaxNotApplied"))
  158. ""
  159. ,(stx->dom-sexp (moby-error-type:syntax-not-applied-keyword error-type)
  160. maybe-dom-parameters)
  161. ": expected an open parenthesis before "
  162. ,(stx->dom-sexp (moby-error-type:syntax-not-applied-keyword error-type)
  163. maybe-dom-parameters)
  164. ", but found none"
  165. )]
  166. ;;fixme: is this ever called?
  167. [(moby-error-type:closing-parenthesis-before-opener? error-type)
  168. `(span ((class "Error-ClosingParenthesisBeforeOpener"))
  169. "Found "
  170. ,(scheme-value->dom-sexp
  171. (moby-error-type:closing-parenthesis-before-opener-closer error-type)
  172. maybe-dom-parameters)
  173. " without it being paired with a left parenthesis.")]
  174. [(moby-error-type:duplicate-identifier? error-type)
  175. `(span ((class "Error-DuplicateIdentifier"))
  176. (span ((class "Error.reason"))
  177. "The variable "
  178. ,(scheme-value->dom-sexp (moby-error-type:duplicate-identifier-id error-type)
  179. maybe-dom-parameters)
  180. " has been duplicated.")
  181. (span ((class "Error-DuplicateIdentifier.secondLocation")
  182. (style "display:none"))
  183. ,(Loc->dom-sexp (moby-error-type:duplicate-identifier-second-location error-type))))]
  184. [(moby-error-type:expected-identifier? error-type)
  185. `(span ((class "Error-ExpectedIdentifier"))
  186. (span ((class "Error.reason"))
  187. "Expected a variable but received "
  188. ,(stx->dom-sexp (moby-error-type:expected-identifier-observed error-type)
  189. maybe-dom-parameters)
  190. " instead."))]
  191. [(moby-error-type:expected-list-of-identifiers? error-type)
  192. `(span ((class "Error-ExpectedListOfIdentifiers"))
  193. (span ((class "Error.reason"))
  194. "Within " ,@(prepend-indefinite-article
  195. (stx->dom-sexp
  196. (moby-error-type:expected-list-of-identifiers-who error-type)
  197. maybe-dom-parameters))
  198. ", expected a list of identifiers but received "
  199. ,(stx->dom-sexp (moby-error-type:expected-list-of-identifiers-observed error-type)
  200. maybe-dom-parameters)
  201. " instead."))]
  202. [(moby-error-type:undefined-identifier? error-type)
  203. `(span ((class "Error-UndefinedIdentifier"))
  204. (span ((class "Error.reason"))
  205. ,(scheme-value->dom-sexp (moby-error-type:undefined-identifier-id error-type)
  206. maybe-dom-parameters)
  207. " is unknown; it's not defined as an input or a primitive."))]
  208. [(moby-error-type:structure-identifier-not-expression? error-type)
  209. `(span ((class "Error-StructureIdentifierNotExpression"))
  210. (span ((class "Error.reason"))
  211. "The structure name "
  212. ,(scheme-value->dom-sexp (moby-error-type:structure-identifier-not-expression-id
  213. error-type)
  214. maybe-dom-parameters)
  215. " can't be used as an expression."))]
  216. [(moby-error-type:provided-name-not-defined? error-type)
  217. `(span ((class "Error-ProvidedNameNotDefined"))
  218. (span ((class "Error.reason"))
  219. "The provided name "
  220. ,(scheme-value->dom-sexp (moby-error-type:provided-name-not-defined-id error-type)
  221. maybe-dom-parameters)
  222. " is not defined in the program."))]
  223. [(moby-error-type:redefinition-not-allowed? error-type)
  224. `(span ((class "Error-RedefinitionNotAllowed"))
  225. (span ((class "Error.reason"))
  226. "The defined name "
  227. ,(scheme-value->dom-sexp
  228. (moby-error-type:redefinition-not-allowed-id error-type)
  229. maybe-dom-parameters)
  230. " is being defined in the program, but it already has a definition that is not allowed to be redefined."))]
  231. [(moby-error-type:unknown-module? error-type)
  232. `(span ((class "Error-UnknownModule"))
  233. (span ((class "Error.reason"))
  234. "Found require of the module "
  235. ,(scheme-value->dom-sexp (moby-error-type:unknown-module-path error-type)
  236. maybe-dom-parameters)
  237. ", but this module is unknown."))]
  238. [(moby-error-type:branch-value-not-boolean? error-type)
  239. `(span ((class "Error-BranchValueNotBoolean"))
  240. "Expected the question's value to be a boolean expression, "
  241. "("
  242. ,(scheme-value->dom-sexp true maybe-dom-parameters)
  243. " or "
  244. ,(scheme-value->dom-sexp false maybe-dom-parameters)
  245. "), "
  246. "but instead found "
  247. ,(scheme-value->dom-sexp
  248. (moby-error-type:branch-value-not-boolean-observed error-type)
  249. maybe-dom-parameters)
  250. ".")]
  251. [(moby-error-type:begin-body-empty? error-type)
  252. `(span ((class "Error-BeginBodyEmpty"))
  253. "Inside a begin, expected to find a body, but nothing was found.")]
  254. [(moby-error-type:boolean-chain-too-few-elements? error-type)
  255. `(span ((class "Error-BooleanChainTooFewElements"))
  256. "Inside an "
  257. ,(scheme-value->dom-sexp (moby-error-type:boolean-chain-too-few-elements-id error-type)
  258. maybe-dom-parameters)
  259. ", expected to see at least two expressions, but both were not found.")]
  260. [(moby-error-type:lambda-too-few-elements? error-type)
  261. `(span ((class "Error-LambdaTooFewElements"))
  262. "Inside a lambda, expected to see a list of arguments and a single body, "
  263. "but both of these were not found.")]
  264. [(moby-error-type:lambda-too-many-elements? error-type)
  265. `(span ((class "Error-LambdaTooManyElements"))
  266. "Inside a lambda, expected to see a list of arguments and a single body, "
  267. "more than two of these were found.")]
  268. [(moby-error-type:missing-expression-following-quote? error-type)
  269. `(span ((class "Error-MissingExpressionFollowingQuote"))
  270. "After a "
  271. ,(stx->dom-sexp (moby-error-type:missing-expression-following-quote-quote-stx error-type)
  272. maybe-dom-parameters)
  273. ", expected to see another expression immediately following it, but none was found.")]
  274. [(moby-error-type:quote-too-few-elements? error-type)
  275. `(span ((class "Error-QuoteTooFewElements"))
  276. "Inside a quote, expected to see a single argument, but none was found.")]
  277. [(moby-error-type:quote-too-many-elements? error-type)
  278. `(span ((class "Error-QuoteTooManyElements"))
  279. "Inside a quote, expected to single a single element, but more than one was found.")]
  280. [(moby-error-type:quasiquote-too-few-elements? error-type)
  281. `(span ((class "Error-QuasiquoteTooFewElements"))
  282. "Inside a quasiquote, expected to find a single argument, but none was found.")]
  283. [(moby-error-type:quasiquote-too-many-elements? error-type)
  284. `(span ((class "Error-QuasiquoteTooManyElements"))
  285. "Inside a quasiquote, expected find a single element, but more than one were found.")]
  286. [(moby-error-type:unquote-too-few-elements? error-type)
  287. `(span ((class "Error-UnquoteTooFewElements"))
  288. "Inside an unquote, expected to find a single argument, but none was found.")]
  289. [(moby-error-type:unquote-too-many-elements? error-type)
  290. `(span ((class "Error-UnquoteTooManyElements"))
  291. "Inside a unquote, expected to find a single element, but more than one were found.")]
  292. [(moby-error-type:unquote-splicing-too-few-elements? error-type)
  293. `(span ((class "Error-UnquoteTooFewElements"))
  294. "Inside an unquote-splicing, expected to find a single argument, but none was found.")]
  295. [(moby-error-type:unquote-splicing-too-many-elements? error-type)
  296. `(span ((class "Error-UnquoteTooManyElements"))
  297. "Inside a unquote-splicing, expected to single a single element, but more than one were found.")]
  298. [(moby-error-type:when-no-body? error-type)
  299. `(span ((class "Error-WhenNoBody"))
  300. "Inside a " (scheme-value->dom-sexp 'when maybe-dom-parameters)
  301. ", expected to find a body, but none was found.")]
  302. [(moby-error-type:unless-no-body? error-type)
  303. `(span ((class "Error-WhenNoBody"))
  304. "Inside an " (scheme-value->dom-sexp 'unless maybe-dom-parameters)
  305. ", expected to find a body, but none was found.")]
  306. [(moby-error-type:check-expect? error-type)
  307. `(span ((class "Error-CheckExpect"))
  308. "Inside a "
  309. ,(scheme-value->dom-sexp 'check-expect maybe-dom-parameters)
  310. ", the observed value "
  311. ,(scheme-value->dom-sexp (moby-error-type:check-expect-observed error-type) maybe-dom-parameters)
  312. " does not match the expected value "
  313. ,(scheme-value->dom-sexp (moby-error-type:check-expect-expected error-type) maybe-dom-parameters)
  314. ".")]
  315. [(moby-error-type:check-within? error-type)
  316. `(span ((class "Error-CheckWithin"))
  317. "Inside a "
  318. ,(scheme-value->dom-sexp 'check-within maybe-dom-parameters)
  319. ", the observed value "
  320. ,(scheme-value->dom-sexp (moby-error-type:check-within-observed error-type) maybe-dom-parameters)
  321. " does not match the expected value "
  322. ,(scheme-value->dom-sexp (moby-error-type:check-within-expected error-type) maybe-dom-parameters)
  323. " within the bounds "
  324. ,(scheme-value->dom-sexp (moby-error-type:check-within-within error-type) maybe-dom-parameters)
  325. ".")]
  326. [(moby-error-type:check-error? error-type)
  327. `(span ((class "Error-CheckError"))
  328. "Inside a "
  329. ,(scheme-value->dom-sexp 'check-expect maybe-dom-parameters)
  330. ", the observed error "
  331. ,(scheme-value->dom-sexp (moby-error-type:check-error-observed error-type) maybe-dom-parameters)
  332. " does not match the expected error "
  333. ,(scheme-value->dom-sexp (moby-error-type:check-error-expected error-type) maybe-dom-parameters)
  334. ".")]
  335. [(moby-error-type:check-error-no-error? error-type)
  336. `(span ((class "Error-CheckErrorNoError"))
  337. "Expected the error "
  338. ,(scheme-value->dom-sexp (moby-error-type:check-error-no-error-expected error-type) maybe-dom-parameters)
  339. " but instead received the value "
  340. ,(scheme-value->dom-sexp (moby-error-type:check-error-no-error-observed error-type) maybe-dom-parameters))]
  341. [(moby-error-type:application-arity? error-type)
  342. `(span ((class "Error-ApplicationArity"))
  343. (span ((class "Error.reason"))
  344. "The function "
  345. ,(scheme-value->dom-sexp (moby-error-type:application-arity-who error-type) maybe-dom-parameters)
  346. " expects "
  347. ,(arity-to-dom-sexp (moby-error-type:application-arity-expected error-type))
  348. " inputs, but instead found "
  349. ,(number->string (moby-error-type:application-arity-observed error-type))
  350. " inputs."))]
  351. [(moby-error-type:application-operator-not-a-function? error-type)
  352. `(span ((class "Error-ApplicationOperatorNotAFunction"))
  353. (span ((class "Error.reason"))
  354. "The operator "
  355. ,(scheme-value->dom-sexp
  356. (moby-error-type:application-operator-not-a-function-who error-type)
  357. maybe-dom-parameters)
  358. " has a value "
  359. ,(scheme-value->dom-sexp
  360. (moby-error-type:application-operator-not-a-function-val error-type)
  361. maybe-dom-parameters)
  362. ", but this value isn't a function."))]
  363. [(moby-error-type:type-mismatch? error-type)
  364. `(span ((class "Error-TypeMismatch"))
  365. (span ((class "Error.reason"))
  366. "The function "
  367. ,(scheme-value->dom-sexp
  368. (moby-error-type:type-mismatch-who error-type)
  369. maybe-dom-parameters)
  370. " expects "
  371. ,@(prepend-indefinite-article
  372. (expected-value-to-dom-sexp
  373. (moby-error-type:type-mismatch-expected error-type)))
  374. " as its "
  375. ,(number->string
  376. (moby-error-type:type-mismatch-position error-type))
  377. ,(ordinal-ending (moby-error-type:type-mismatch-position error-type))
  378. " argument, but instead found "
  379. ,(scheme-value->dom-sexp
  380. (moby-error-type:type-mismatch-observed error-type)
  381. maybe-dom-parameters)
  382. "."))]
  383. [(moby-error-type:index-out-of-bounds? error-type)
  384. `(span ((class "Error-IndexOutOfBounds"))
  385. (span ((class "Error.reason"))
  386. "The index "
  387. ,(scheme-value->dom-sexp
  388. (moby-error-type:index-out-of-bounds-observed error-type)
  389. maybe-dom-parameters)
  390. " is not within the expected boundary ["
  391. ,(scheme-value->dom-sexp
  392. (moby-error-type:index-out-of-bounds-minimum error-type)
  393. maybe-dom-parameters)
  394. ", "
  395. ,(scheme-value->dom-sexp
  396. (moby-error-type:index-out-of-bounds-maximum error-type)
  397. maybe-dom-parameters)
  398. "]"
  399. ))]
  400. [(moby-error-type:conditional-exhausted? error-type)
  401. `(span ((class "Error-ConditionalExhausted"))
  402. (span ((class "Error.reason"))
  403. "All of the questions inside a cond were false, "
  404. "and at least one of them has to be true."))]
  405. [(moby-error-type:generic-runtime-error? error-type)
  406. `(span ((class "Error-GenericRuntimeError"))
  407. (span ((class "Error.reason"))
  408. ,(moby-error-type:generic-runtime-error-reason error-type)))]
  409. [(moby-error-type:generic-syntactic-error? error-type)
  410. `(span ((class "Error-GenericSyntacticError"))
  411. (span ((class "Error.reason"))
  412. ,(moby-error-type:generic-syntactic-error-reason error-type))
  413. (span ((class "Error-GenericSyntacticError.otherLocations"))
  414. ,@(map Loc->dom-sexp
  415. (moby-error-type:generic-syntactic-error-other-locations error-type))))]
  416. [(moby-error-type:generic-read-error? error-type)
  417. `(span ((class "Error-GenericReadError"))
  418. (span ((class "Error.reason"))
  419. ,(moby-error-type:generic-read-error-message error-type))
  420. (span ((class "Error-GenericReadError.locations"))
  421. ,@(map Loc->dom-sexp
  422. (moby-error-type:generic-read-error-locations error-type))))]
  423. [else
  424. (error 'error-struct-to-dom "Could not convert ~a" error-type)]))))
  425. ;; Loc->dom-sexp: loc -> sexp
  426. ;; Given a location, produce a dom representation of that location.
  427. (define (Loc->dom-sexp a-loc)
  428. `(span ((class "location-reference")
  429. (style "display:none"))
  430. (span ((class "location-offset")) ,(number->string (Loc-offset a-loc)))
  431. (span ((class "location-line")) ,(number->string (Loc-line a-loc)))
  432. (span ((class "location-column")) ,(number->string (Loc-column a-loc)))
  433. (span ((class "location-span")) ,(number->string (Loc-span a-loc)))
  434. (span ((class "location-id")) ,(Loc-id a-loc))))
  435. ;; separate-with-br-elements: (listof dom) -> (listof dom)
  436. ;; Splice in br elements between each dom.
  437. (define (separate-with-br-elements doms)
  438. (cond
  439. [(empty? doms)
  440. empty]
  441. [(empty? (rest doms))
  442. (list (first doms))]
  443. [else
  444. (cons (first doms)
  445. '(br ())
  446. (separate-with-br-elements (rest doms)))]))
  447. ;; ordinal-ending: natural-number -> string
  448. ;; Produces the ordinal ending of a number. For example, 1 => st, 4 => th.
  449. (define (ordinal-ending n)
  450. (cond
  451. [(= (modulo (quotient n 10) 10) 1)
  452. "th"]
  453. [else
  454. (list-ref '("th" "st" "nd" "rd" "th"
  455. "th" "th" "th" "th" "th")
  456. (modulo n 10))]))
  457. ;; prepend-indefinite-article: dom -> (listof dom)
  458. ;; Produces a list containting the appropriate indefinite article and the dom.
  459. (define (prepend-indefinite-article a-dom)
  460. (list (indefinite-article (dom-string-content a-dom))
  461. " "
  462. a-dom))
  463. ;; indefinite-article: string -> string
  464. ;; Tries to get the indefinite article of a word.
  465. (define (indefinite-article a-word)
  466. (cond
  467. [(begins-with-vowel-sound? a-word)
  468. "an"]
  469. [else
  470. "a"]))
  471. ;; begins-with-vowel-sound?: string -> boolean
  472. ;; Tries to produces true if there's a vowel sound at the beginning of the
  473. ;; word.
  474. ;; This is not quite right because it doesn't use a dictionary.
  475. (define (begins-with-vowel-sound? a-word)
  476. (cond
  477. [(= 0 (string-length a-word))
  478. false]
  479. [(vowel-character? (string-ref a-word 0))
  480. true]
  481. ;; Check to see if it's a "y" vowel sound
  482. [(and (> (string-length a-word) 2)
  483. (char=? (string-ref a-word 0) #\y)
  484. (not (vowel-character? (string-ref a-word 1))))
  485. true]
  486. [else
  487. false]))
  488. ;; vowel-character?: char -> boolean
  489. ;; Produces true if the given character is a vowel character.
  490. (define (vowel-character? a-char)
  491. (member a-char '(#\a #\e #\i #\o #\u)))
  492. ;; stx-to-dom-sexp: stx -> dom
  493. ;; Converts a stx to a dom s-expression.
  494. (define (stx->dom-sexp a-stx maybe-dom-parameters)
  495. (scheme-value->dom-sexp (stx->datum a-stx) maybe-dom-parameters))
  496. ;; expected-value-to-dom-sexp: moby-expected -> dom
  497. ;; Translates an expectation to a dom.
  498. (define (expected-value-to-dom-sexp expected)
  499. (cond
  500. [(moby-expected:string? expected)
  501. `(span ((class "Expected-String"))
  502. "string")]
  503. [(moby-expected:integer? expected)
  504. `(span ((class "Expected-Integer"))
  505. "integer")]
  506. [(moby-expected:natural? expected)
  507. `(span ((class "Expected-Natural"))
  508. "natural")]
  509. [(moby-expected:rational? expected)
  510. `(span ((class "Expected-Rational"))
  511. "rational")]
  512. [(moby-expected:real? expected)
  513. `(span ((class "Expected-Real"))
  514. "real")]
  515. [(moby-expected:complex? expected)
  516. `(span ((class "Expected-Complex"))
  517. "complex")]
  518. [(moby-expected:number? expected)
  519. `(span ((class "Expected-Number"))
  520. "number")]
  521. [(moby-expected:boolean? expected)
  522. `(span ((class "Expected-Boolean"))
  523. "boolean")]
  524. [(moby-expected:char? expected)
  525. `(span ((class "Expected-Char"))
  526. "char")]
  527. [(moby-expected:symbol? expected)
  528. `(span ((class "Expected-Symbol"))
  529. "symbol")]
  530. [(moby-expected:list? expected)
  531. `(span ((class "Expected-List"))
  532. "list")]
  533. [(moby-expected:listof? expected)
  534. `(span ((class "Expected-Listof"))
  535. "list of "
  536. (expected-value-to-dom-sexp (moby-expected:listof-thing expected))
  537. "" )]
  538. [(moby-expected:vector? expected)
  539. `(span ((class "Expected-Vector"))
  540. "vector")]
  541. [(moby-expected:struct? expected)
  542. `(span ((class "Expected-Struct"))
  543. "struct")]
  544. [(moby-expected:box? expected)
  545. `(span ((class "Expected-Box"))
  546. "box")]
  547. [(moby-expected:hash? expected)
  548. `(span ((class "Expected-Hash"))
  549. "hash")]
  550. [(moby-expected:function? expected)
  551. `(span ((class "Expected-Function"))
  552. "function")]
  553. [(moby-expected:something? expected)
  554. `(span ((class "Expected-Something"))
  555. ,(moby-expected:something-description expected))]))
  556. ;; Converts an arity to a dom sexpression.
  557. (define (arity-to-dom-sexp an-arity)
  558. (cond
  559. [(arity:fixed? an-arity)
  560. `(span ((class "Arity-Fixed"))
  561. ,(number->string (arity:fixed-n an-arity)))]
  562. [(arity:variable? an-arity)
  563. `(span ((class "Arity-Variable"))
  564. (span ((class "Arity-Variable.minimum"))
  565. ,(number->string (arity:variable-min an-arity)))
  566. (span ((class "Arity-Variable.maximum"))
  567. ,(number->string (arity:variable-max an-arity))))]
  568. [(arity:mixed? an-arity)
  569. `(span ((class "Arity-Mixed"))
  570. ,@(map (lambda (a)
  571. `(span ((class "Arity-Mixed.item"))
  572. ,(arity-to-dom-sexp a)))))]))
  573. (provide/contract
  574. [error-struct->dom-sexp (any/c (or/c false/c dom-parameters?) . -> . any)]
  575. [error-struct->jsexpr (any/c . -> . any)]
  576. [loc->jsexpr (Loc? . -> . any)])