source: tags/1.5.0/contrib/jss/read-sharp-quote-expression.lisp

Last change on this file was 15063, checked in by Mark Evenson, 7 years ago

Utility for jss
(Alan Ruttenberg)

From <https://github.com/armedbear/abcl/pull/52/commits/987c18f0c50152f1bf7dfa2318660f85575cfd81>.

Part of merge <https://github.com/armedbear/abcl/pull/52/>.

File size: 3.9 KB
Line 
1(in-package :jss)
2
3(defclass sharp-quote-expression-reader (javaparser) ())
4
5(defun read-sharp-java-expression (stream)
6  (read-sharp-quote-expression
7     (with-output-to-string (s)
8       (loop with embedded-string = nil
9       for last = #\space then char
10       for char = (read-char stream)
11       until (and (char= char #\") 
12      ;; really end if: we've established embedded string and the peek is a space
13      ;; we're not about to start embedded string. We're about to start embedded string if next character isn't #\).
14      ;; we're not embedded-string and not about to start one
15      (cond ((null (peek-char nil stream nil)) t) ;; eof
16            (embedded-string (system:whitespacep (peek-char nil stream))) ; embedded " needs "<space>" to end
17            ((find last ",(+=" :test 'char=)
18             (setq embedded-string t)
19             nil)
20            (t t)))
21       do
22    (write-char char s)))))
23
24
25(defun read-sharp-quote-expression (string)
26  (multiple-value-bind (bindings de-lisped) (extract-lisp-expressions string)
27    (let ((read (read-java-expression (make-instance 'sharp-quote-expression-reader) de-lisped)))
28      (loop for (var nil) in bindings
29      do (setq read (cl-user::tree-replace (lambda(e) (if (equalp e (string var)) var e)) read )))
30      (if bindings
31    `(let ,bindings ,read)
32    read))))
33
34(defun extract-lisp-expressions (string)
35  (let ((bindings nil))
36    (let ((de-lisped
37      (cl-user::replace-all string "\\{(.*?)\\}" 
38          (lambda(match) 
39            (let ((replacevar (find-symbol-not-matching string (mapcar 'car bindings))))
40              (push (list replacevar (read-from-string match)) bindings)
41              (string replacevar)))
42          1)))
43    (values bindings de-lisped))))
44
45(defun find-symbol-not-matching (string already)
46  (loop for candidate = (format nil "JSS_~a" (random 10000))
47  until (and (not (member candidate already :test 'equalp :key 'string))
48       (not (search string already)))
49  finally (return-from find-symbol-not-matching (intern candidate :jss))))
50         
51(defun maybe-class (el)
52  (if (and (symbolp el) (upper-case-p (char (string el) 0)) (not (eql (search "JSS_" (string el)) 0)))
53      `(find-java-class ',el)
54      (if (symbolp el)
55    (intern (string-upcase el) :jss)
56    el)))
57
58(def-java-read ObjectCreationExpr sharp-quote-expression-reader ()
59  `(new ',(process-node obj (#"getName" (#"getType" node))) ,@(mapcar (lambda(e) (process-node obj e)) (j2list (#"getArguments" node))))
60  )
61
62(def-java-read MethodCallExpr sharp-quote-expression-reader ()
63  (let* ((scope1 (process-node obj (process-node obj (#"getScope" node))))
64   (how  (if (and (symbolp scope1) (not (null scope1)) (upper-case-p (char (string scope1) 0))) 
65       'jstatic
66       'jcall)))
67    (if (and (symbolp scope1) (not (null scope1)) (upper-case-p (char (string scope1) 0)))
68  (setq scope1 `',scope1))
69    `(,how ,(#"getIdentifier" (#"getName" node)) ,(or scope1 'this) ,@(mapcar 'maybe-class 
70                        (mapcar (lambda(el) (process-node obj el))
71                          (j2list (#"getArguments" node)))))
72    ))
73
74
75(def-java-read FieldAccessExpr sharp-quote-expression-reader ()
76  (let ((scope (process-node obj (#"getScope" node))))
77    (if (and (symbolp scope) (upper-case-p (char (string scope) 0)))
78  `(get-java-field ',(process-node obj (#"getScope" node)) ,(#"getIdentifier" (#"getField" node)) t)
79  `(get-java-field ,(maybe-class (process-node obj (#"getScope" node))) ,(#"getIdentifier" (#"getField" node)) t))))
80
81(def-java-read ArrayAccessExpr sharp-quote-expression-reader ()
82  (let ((index (process-node obj (#"getIndex" node))))
83    (if (symbolp index) (setq index (intern (string-upcase index))))
84    `(aref ,(process-node obj (#"getName" node)) ,index)))
85
86(def-java-read ClassExpr sharp-quote-expression-reader ()
87  (let ((name (process-node obj (#"getName" (#"getType" node)))))
88    (if (eql (search "JSS_" (string name) :test 'equalp) 0)
89  name
90  `(find-java-class ',name))))
91
92(def-java-read NameExpr sharp-quote-expression-reader ()
93  (process-node obj (#"getName" node)))
94
Note: See TracBrowser for help on using the repository browser.