summaryrefslogtreecommitdiff
path: root/src/json/json.lisp
blob: e20c529aa8a21134bff0967639a9991715e9189b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
(in-package :json)

(defparameter *json* "{\"hello\": 55}")

(defclass json-okur ()
  ((arabellek :accessor arabellek
              :initarg :arabellek
              :type string)
   (uzunluk :accessor uzunluk
            :initarg :uzunluk
            :type integer)
   (i :accessor i
      :initform 0
      :type integer)
   (ch :accessor ch
       :type character)
   (ch2 :accessor ch2
        :type character)))

(defparameter +eof+ (code-char 0))

(defun eof? (ch)
  (char= +eof+ ch))

(defun yeni (arabellek &optional (uzunluk (length arabellek)))
  (let ((okur (make-instance 'json-okur :arabellek arabellek :uzunluk uzunluk)))
    (char-gözat! okur)
    okur))

(defmethod reset ((o json-okur))
  (setf (i o) 0)
  (char-gözat! o))

(defmethod index ((o json-okur))
  (- (i o) 2))

(defmethod char-oynat ((o json-okur))
  (setf (ch o) (ch2 o))
  (char-gözat! o)
  (ch o))

(defmethod char-gözat ((o json-okur))
  (ch2 o))

(defmethod char-gözat! ((o json-okur))
  "Sonraki karaktere bak ve kaydet"
  (with-slots (i uzunluk arabellek ch2) o
    (cond ((array-in-bounds-p arabellek i)
           (setf ch2 (aref arabellek i))
           (incf i))
          (t
           (setf ch2 +eof+)))))

(defun boşluk? (ch)
  (find ch #(#\Space #\Newline #\Return #\Tab)))

(defmethod boşluk-geç ((o json-okur))
  (loop :while (boşluk? (char-gözat o))
        :do (char-oynat o)))

(defmethod metin-oku ((o json-okur))
  (let* ((baş (+ 1 (index o))))
    (loop :for char := (char-oynat o)
          :until (char= #\" char))
    (subseq (arabellek o) baş (index o))))

(defmethod rakam? (ch)
  (char<= #\0 ch #\9))

(defmethod sayı-oku ((o json-okur))
  (let* ((baş (index o)))
    (loop :for char := (char-gözat o)
          :while (rakam? char)
          :do (char-oynat o))
    (subseq (arabellek o) baş (+ 1 (index o)))))

(defmethod token-oku ((o json-okur))
  (case (char-oynat o)
    (#\{ :süslü-aç)
    (#\} :süslü-kapa)
    (#\: :iki-nokta)
    (#\" (list :string (metin-oku o)))
    (otherwise (cond ((rakam? (ch o))
                      (list :sayı (sayı-oku o)))
                     ((boşluk? (ch o))
                      (boşluk-geç o))
                     ((eof? (ch o))
                      :eof)))))

(defmethod işle ((o json-okur))
  (loop :for token := (token-oku o)
        :collect token
        :until (eq :eof token)))