compiler-helpers.lisp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. (import urn/logger/void logger)
  2. (import urn/library ())
  3. (import urn/range ())
  4. (import urn/resolve/builtins builtins)
  5. (import urn/resolve/scope scope)
  6. (import urn/resolve/native native)
  7. (import urn/timer timer)
  8. (import urn/traceback traceback)
  9. (import lua/basic (type#))
  10. (import lua/basic b)
  11. (define start-range
  12. "The default range for all objects"
  13. :hidden
  14. (mk-range "init.lisp"
  15. (mk-position 1 1 1)
  16. (mk-position 1 1 1)
  17. '(";; Empty")))
  18. (defun wrap-node (node)
  19. "Wraps a NODE, converting it into something usable for resolution."
  20. (case (type# node)
  21. ["number" { :tag "number" :value node :range start-range }]
  22. ["string" { :tag "string" :value node :range start-range }]
  23. ["table"
  24. (.<! node :range start-range)
  25. (when (list? node)
  26. (for i 1 (n node) 1
  27. (.<! node i (wrap-node (nth node i)))))
  28. node]))
  29. (defun native-expr (data)
  30. (with (native (native/native))
  31. (native/set-native-pure! native (.> data :pure))
  32. (native/set-native-syntax! native (.> data :contents))
  33. (native/set-native-syntax-arity! native (.> data :count))
  34. (native/set-native-syntax-precedence! native (.> data :prec))
  35. (native/set-native-syntax-fold! native (.> data :fold))
  36. native))
  37. (defun native-var (name)
  38. (with (native (native/native))
  39. (native/set-native-bind-to! native name)
  40. native))
  41. (defun create-compiler ()
  42. "Create a new compilation state, with some basic variables already defined."
  43. (let* [(scope (builtins/create-scope "top-level"))
  44. (libs (library-cache))
  45. (compiler { :log logger/void
  46. :timer (timer/void)
  47. :libs libs
  48. :root-scope scope
  49. :exec (lambda (func) (list (xpcall func traceback/traceback)))
  50. :variables {}
  51. :states {}
  52. :global (b/setmetatable {} { :__index b/_G })
  53. :compile-state { :mappings {} }
  54. :loader (lambda (name) (format 0 "Cannot load external module {#name:string/quoted}")) })]
  55. ;; Setup meta definitions
  56. (set-library-cache-meta! libs :+ (native-expr { :contents '(1 " + " 2) :count 2 :fold "left" :prec 9 :pure true }))
  57. (set-library-cache-meta! libs :- (native-expr { :contents '(1 " - " 2) :count 2 :fold "left" :prec 9 :pure true }))
  58. (set-library-cache-meta! libs :.. (native-expr { :contents '(1 " .. " 2) :count 2 :fold "right" :prec 8 :pure true }))
  59. (set-library-cache-meta! libs := (native-expr { :contents '(1 " == " 2) :count 2 :prec 3 :pure true }))
  60. (set-library-cache-meta! libs :>= (native-expr { :contents '(1 " >= " 2) :count 2 :prec 3 :pure true }))
  61. (set-library-cache-meta! libs :get-idx (native-expr { :contents '(1 "[" 2 "]") :count 2 :prec '(100 0) }))
  62. (set-library-cache-meta! libs :print (native-var "print"))
  63. ;; Setup main definitions
  64. (for-each name '("foo" "bar" "baz" "qux" "+" "-" ".." "=" ">=" "get-idx" "print")
  65. (with (var (scope/add! scope name "native"))
  66. (when-with (native (library-cache-meta libs name))
  67. (scope/set-var-native! var native))))
  68. (for-pairs (_ var) (scope/scope-variables (scope/scope-parent scope)) (.<! compiler :variables (tostring var) var))
  69. (for-pairs (_ var) (scope/scope-variables scope) (.<! compiler :variables (tostring var) var))
  70. compiler))
  71. (defun tracking-logger ()
  72. "A logger which tracks error messages."
  73. (let* [(errors '())
  74. (warnings '())
  75. (discard (lambda ()))
  76. (pusher (lambda (out)
  77. (lambda (logger msg source explain lines)
  78. (with (buffer (list msg))
  79. (for i 2 (n lines) 2
  80. (with (line (nth lines i))
  81. (when (/= line "") (push! buffer line))))
  82. (push! out (concat buffer "\n"))))))]
  83. { :put-error! (lambda (self msg) (push! errors msg))
  84. :put-warning! (lambda (self msg) (push! warnings msg))
  85. :put-verbose! discard
  86. :put-debug! discard
  87. :put-time! discard
  88. :put-node-error! (pusher errors)
  89. :put-node-warning! (pusher warnings)
  90. :errors errors
  91. :warnings warnings }))