<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # [X分鐘速成Y](http://learnxinyminutes.com/) ## 其中 Y=Common Lisp 源代碼下載:?[commonlisp-cn.lisp](http://learnxinyminutes.com/docs/files/commonlisp-cn.lisp) ANSI Common Lisp 是一個廣泛通用于各個工業領域的、支持多種范式的編程語言。 這門語言也經常被引用作“可編程的編程語言”(可以寫代碼的代碼)。 免費的經典的入門書籍[《實用 Common Lisp 編程》](http://www.gigamonkeys.com/book/) 另外還有一本熱門的近期出版的?[Land of Lisp](http://landoflisp.com/). ~~~ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 0\. 語法 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 一般形式 ;; Lisp有兩個基本的語法單元:原子(atom),以及S-表達式。 ;; 一般的,一組S-表達式被稱為“組合式”。 10 ; 一個原子; 它對自身進行求值 :THING ;同樣是一個原子;它被求值為一個符號 :thing t ;還是一個原子,代表邏輯真值。 (+ 1 2 3 4) ; 一個S-表達式。 '(4 :foo t) ;同樣是一個S-表達式。 ;;; 注釋 ;; 一個分號開頭的注釋表示僅用于此行(單行);兩個分號開頭的則表示一個所謂標準注釋; ;; 三個分號開頭的意味著段落注釋; ;; 而四個分號開頭的注釋用于文件頭注釋(譯者注:即對該文件的說明)。 #| 塊注釋 可以涵蓋多行,而且... #| 他們可以被嵌套! |# |# ;;; 運行環境 ;; 有很多不同的Common Lisp的實現;并且大部分的實現是一致(可移植)的。 ;; 對于入門學習來說,CLISP是個不錯的選擇。 ;; 可以通過QuickLisp.org的Quicklisp系統管理你的庫。 ;; 通常,使用文本編輯器和“REPL”來開發Common Lisp; ;; (譯者注:“REPL”指讀取-求值-打印循環)。 ;; “REPL”允許對程序進行交互式的運行、調試,就好像在系統“現場”操作。 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 1\. 基本數據類型以及運算符 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 符號 'foo ; => FOO 注意到這個符號被自動轉換成大寫了。 ;; `intern`由一個給定的字符串而創建相應的符號 (intern "AAAA") ; => AAAA (intern "aaa") ; => |aaa| ;;; 數字 9999999999999999999999 ; 整型數 #b111 ; 二進制 => 7 #o111 ; 八進制 => 73 #x111 ; 十六進制 => 273 3.14159s0 ; 單精度 3.14159d0 ; 雙精度 1/2 ; 分數 #C(1 2) ; 復數 ;; 使用函數時,應當寫成這樣的形式:(f x y z ...); ;; 其中,f是一個函數(名),x, y, z為參數; ;; 如果你想創建一個“字面”意義上(即不求值)的列表, 只需使用單引號 ' , ;; 從而避免接下來的表達式被求值。即,只“引用”這個數據(而不求值)。 '(+ 1 2) ; => (+ 1 2) ;; 你同樣也可以手動地調用一個函數(譯者注:即使用函數對象來調用函數): (funcall #'+ 1 2 3) ; => 6 ;; 一些算術運算符 (+ 1 1) ; => 2 (- 8 1) ; => 7 (* 10 2) ; => 20 (expt 2 3) ; => 8 (mod 5 2) ; => 1 (/ 35 5) ; => 7 (/ 1 3) ; => 1/3 (+ #C(1 2) #C(6 -4)) ; => #C(7 -2) ;;; 布爾運算 t ; 邏輯真(任何不是nil的值都被視為真值) nil ; 邏輯假,或者空列表 (not nil) ; => t (and 0 t) ; => t (or 0 nil) ; => 0 ;;; 字符 #\A ; => #\A #\λ ; => #\GREEK_SMALL_LETTER_LAMDA(希臘字母Lambda的小寫) #\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA(Unicode形式的小寫希臘字母Lambda) ;;; 字符串被視為一個定長字符數組 "Hello, world!" "Benjamin \"Bugsy\" Siegel" ;反斜杠用作轉義字符 ;; 可以拼接字符串 (concatenate 'string "Hello " "world!") ; => "Hello world!" ;; 一個字符串也可被視作一個字符序列 (elt "Apple" 0) ; => #\A ;; `format`被用于格式化字符串 (format nil "~a can be ~a" "strings" "formatted") ;; 利用`format`打印到屏幕上是非常簡單的 ;;(譯者注:注意到第二個參數是t,不同于剛剛的nil);~% 代表換行符 (format t "Common Lisp is groovy. Dude.~%") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 2\. 變量 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 你可以通過`defparameter`創建一個全局(動態)變量 ;; 變量名可以是除了:()[]{}",'`;#|\ 這些字符之外的其他任何字符 ;; 動態變量名應該由*號開頭與結尾! ;; (譯者注:這個只是一個習慣) (defparameter *some-var* 5) *some-var* ; => 5 ;; 你也可以使用Unicode字符: (defparameter *AΛB* nil) ;; 訪問一個在之前從未被綁定的變量是一種不規范的行為(即使依然是可能發生的); ;; 不要嘗試那樣做。 ;; 局部綁定:在(let ...)語句內,'me'被綁定到"dance with you"上。 ;; `let`總是返回在其作用域內最后一個表達式的值 (let ((me "dance with you")) me) ;; => "dance with you" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 3\. 結構體和集合 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 結構體 (defstruct dog name breed age) (defparameter *rover* (make-dog :name "rover" :breed "collie" :age 5)) *rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5) (dog-p *rover*) ; => t ;; ewww) (dog-name *rover*) ; => "rover" ;; Dog-p,make-dog,以及 dog-name都是由defstruct創建的! ;;; 點對單元(Pairs) ;; `cons`可用于生成一個點對單元, 利用`car`以及`cdr`將分別得到第一個和第二個元素 (cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB) (car (cons 'SUBJECT 'VERB)) ; => SUBJECT (cdr (cons 'SUBJECT 'VERB)) ; => VERB ;;; 列表 ;; 所有列表都是由點對單元構成的“鏈表”。它以'nil'(或者'())作為列表的最后一個元素。 (cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3) ;; `list`是一個生成列表的便利途徑 (list 1 2 3) ; => '(1 2 3) ;; 并且,一個引用也可被用做字面意義上的列表值 '(1 2 3) ; => '(1 2 3) ;; 同樣的,依然可以用`cons`來添加一項到列表的起始位置 (cons 4 '(1 2 3)) ; => '(4 1 2 3) ;; 而`append`也可用于連接兩個列表 (append '(1 2) '(3 4)) ; => '(1 2 3 4) ;; 或者使用`concatenate` (concatenate 'list '(1 2) '(3 4)) ;; 列表是一種非常核心的數據類型,所以有非常多的處理列表的函數 ;; 例如: (mapcar #'1+ '(1 2 3)) ; => '(2 3 4) (mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33) (remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4) (every #'evenp '(1 2 3 4)) ; => nil (some #'oddp '(1 2 3 4)) ; => T (butlast '(subject verb object)) ; => (SUBJECT VERB) ;;; 向量 ;; 向量的字面意義是一個定長數組 ;;(譯者注:此處所謂“字面意義”,即指#(......)的形式,下文還會出現) #(1 2 3) ; => #(1 2 3) ;; 使用`concatenate`來將兩個向量首尾連接在一起 (concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6) ;;; 數組 ;; 向量和字符串只不過是數組的特例 ;; 二維數組 (make-array (list 2 2)) ;; (make-array '(2 2)) 也是可以的 ; => #2A((0 0) (0 0)) (make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0))) ;; 注意:數組的默認初始值是可以指定的 ;; 下面是如何指定的示例: (make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET) ;; 若想獲取數組[1][1][1]上的元素: (aref (make-array (list 2 2 2)) 1 1 1) ; => 0 ;;; 變長向量 ;; 若將變長向量打印出來,那么它的字面意義上的值和定長向量的是一樣的 (defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3) :adjustable t :fill-pointer t)) *adjvec* ; => #(1 2 3) ;; 添加新的元素: (vector-push-extend 4 *adjvec*) ; => 3 *adjvec* ; => #(1 2 3 4) ;;; 不怎么嚴謹地說,集合也可被視為列表 (set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1) (intersection '(1 2 3 4) '(4 5 6 7)) ; => 4 (union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7) (adjoin 4 '(1 2 3 4)) ; => (1 2 3 4) ;; 然而,你可能想使用一個更好的數據結構,而并非一個鏈表 ;;; 在Common Lisp中,“字典”和哈希表的實現是一樣的。 ;; 創建一個哈希表 (defparameter *m* (make-hash-table)) ;; 給定鍵,設置對應的值 (setf (gethash 'a *m*) 1) ;; (通過鍵)檢索對應的值 (gethash 'a *m*) ; => 1, t ;; 注意此處有一細節:Common Lisp往往返回多個值。`gethash`返回的兩個值是t,代表找到了這個元素;返回nil表示沒有找到這個元素。 ;;(譯者注:返回的第一個值表示給定的鍵所對應的值或者nil;) ;;(第二個是一個布爾值,表示在哈希表中是否存在這個給定的鍵) ;; 例如,如果可以找到給定的鍵所對應的值,則返回一個t,否則返回nil ;; 由給定的鍵檢索一個不存在的值,則返回nil ;;(譯者注:這個nil是第一個nil,第二個nil其實是指該鍵在哈希表中也不存在) (gethash 'd *m*) ;=> nil, nil ;; 給定一個鍵,你可以指定其對應的默認值: (gethash 'd *m* :not-found) ; => :NOT-FOUND ;; 在此,讓我們看一看怎樣處理`gethash`的多個返回值。 (multiple-value-bind (a b) (gethash 'd *m*) (list a b)) ; => (NIL NIL) (multiple-value-bind (a b) (gethash 'a *m*) (list a b)) ; => (1 T) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 3\. 函數 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 使用`lambda`來創建一個匿名函數。 ;; 一個函數總是返回其形式體內最后一個表達式的值。 ;; 將一個函數對象打印出來后的形式是多種多樣的... (lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}> ;; 使用`funcall`來調用lambda函數 (funcall (lambda () "Hello World")) ; => "Hello World" ;; 或者使用`apply` (apply (lambda () "Hello World") nil) ; => "Hello World" ;; 顯式地定義一個函數(譯者注:即非匿名的) (defun hello-world () "Hello World") (hello-world) ; => "Hello World" ;; 剛剛上面函數名"hello-world"后的()其實是函數的參數列表 (defun hello (name) (format nil "Hello, ~a " name)) (hello "Steve") ; => "Hello, Steve" ;; 函數可以有可選形參并且其默認值都為nil (defun hello (name &optional from) (if from (format t "Hello, ~a, from ~a" name from) (format t "Hello, ~a" name))) (hello "Jim" "Alpacas") ;; => Hello, Jim, from Alpacas ;; 你也可以指定那些可選形參的默認值 (defun hello (name &optional (from "The world")) (format t "Hello, ~a, from ~a" name from)) (hello "Steve") ; => Hello, Steve, from The world (hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas ;; 當然,你也可以設置所謂關鍵字形參; ;; 關鍵字形參往往比可選形參更具靈活性。 (defun generalized-greeter (name &key (from "the world") (honorific "Mx")) (format t "Hello, ~a ~a, from ~a" honorific name from)) (generalized-greeter "Jim") ; => Hello, Mx Jim, from the world (generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr") ; => Hello, Mr Jim, from the alpacas you met last summer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 4\. 等式 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Common Lisp具有一個十分復雜的用于判斷等價的系統,下面只是其中一部分的例子 ;; 若要比較數值是否等價,使用`=` (= 3 3.0) ; => t (= 2 1) ; => nil ;; 若要比較對象的類型,則使用`eql` ;;(譯者注:抱歉,翻譯水平實在有限,下面是我個人的補充說明) ;;(`eq` 返回真,如果對象的內存地址相等) ;;(`eql` 返回真,如果兩個對象內存地址相等,或者對象的類型相同,并且值相等) ;;(例如同為整形數或浮點數,并且他們的值相等時,二者`eql`等價) ;;(想要弄清`eql`,其實有必要先了解`eq`) ;;([可以參考](http://stackoverflow.com/questions/547436/whats-the-difference-between-eq-eql-equal-and-equalp-in-common-lisp)) ;;(可以去CLHS上分別查看兩者的文檔) ;;(另外,《實用Common Lisp編程》的4.8節也提到了兩者的區別) (eql 3 3) ; => t (eql 3 3.0) ; => nil (eql (list 3) (list 3)) ; => nil ;; 對于列表、字符串、以及位向量,使用`equal` (equal (list 'a 'b) (list 'a 'b)) ; => t (equal (list 'a 'b) (list 'b 'a)) ; => nil ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 5\. 控制流 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 條件判斷語句 (if t ; “test”,即判斷語句 "this is true" ; “then”,即判斷條件為真時求值的表達式 "this is false") ; “else”,即判斷條件為假時求值的表達式 ; => "this is true" ;; 在“test”(判斷)語句中,所有非nil或者非()的值都被視為真值 (member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO) (if (member 'Groucho '(Harpo Groucho Zeppo)) 'yep 'nope) ; => 'YEP ;; `cond`將一系列測試語句串聯起來,并對相應的表達式求值 (cond ((> 2 2) (error "wrong!")) ((< 2 2) (error "wrong again!")) (t 'ok)) ; => 'OK ;; 對于給定值的數據類型,`typecase`會做出相應地判斷 (typecase 1 (string :string) (integer :int)) ; => :int ;;; 迭代 ;; 當然,遞歸是肯定被支持的: (defun walker (n) (if (zerop n) :walked (walker (1- n)))) (walker) ; => :walked ;; 而大部分場合下,我們使用`DOLIST`或者`LOOP`來進行迭代 (dolist (i '(1 2 3 4)) (format t "~a" i)) ; => 1234 (loop for i from 0 below 10 collect i) ; => (0 1 2 3 4 5 6 7 8 9) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 6\. 可變性 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 使用`setf`可以對一個已經存在的變量進行賦值; ;; 事實上,剛剛在哈希表的例子中我們已經示范過了。 (let ((variable 10)) (setf variable 2)) ; => 2 ;; 所謂好的Lisp編碼風格就是為了減少使用破壞性函數,防止發生副作用。 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 7\. 類與對象 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 我們就不寫什么有關動物的類了,下面給出的人力車的類 (defclass human-powered-conveyance () ((velocity :accessor velocity :initarg :velocity) (average-efficiency :accessor average-efficiency :initarg :average-efficiency)) (:documentation "A human powered conveyance")) ;; `defclass`,后面接類名,以及超類列表 ;; 再接著是槽的列表(槽有點像Java里的成員變量),最后是一些可選的特性 ;; 例如文檔說明“:documentation” ;; 如果超類列表為空,則默認該類繼承于“standard-object”類(standard-object又是T的子類) ;; 這種默認行為是可以改變的,但你最好有一定的基礎并且知道自己到底在干什么; ;; 參閱《The Art of the Metaobject Protocol》來了解更多信息。 (defclass bicycle (human-powered-conveyance) ((wheel-size :accessor wheel-size :initarg :wheel-size :documentation "Diameter of the wheel.") (height :accessor height :initarg :height))) (defclass recumbent (bicycle) ((chain-type :accessor chain-type :initarg :chain-type))) (defclass unicycle (human-powered-conveyance) nil) (defclass canoe (human-powered-conveyance) ((number-of-rowers :accessor number-of-rowers :initarg :number-of-rowers))) ;; 在REPL中對human-powered-conveyance類調用`DESCRIBE`后結果如下: (describe 'human-powered-conveyance) ; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE ; [symbol] ; ; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS ; HUMAN-POWERED-CONVEYANCE>: ; Documentation: ; A human powered conveyance ; Direct superclasses: STANDARD-OBJECT ; Direct subclasses: UNICYCLE, BICYCLE, CANOE ; Not yet finalized. ; Direct slots: ; VELOCITY ; Readers: VELOCITY ; Writers: (SETF VELOCITY) ; AVERAGE-EFFICIENCY ; Readers: AVERAGE-EFFICIENCY ; Writers: (SETF AVERAGE-EFFICIENCY) ;; 注意到這些有用的返回信息——Common Lisp一直是一個交互式的系統。 ;; 若要定義一個方法; ;; 注意,我們計算自行車輪子周長時使用了這樣一個公式:C = d * pi (defmethod circumference ((object bicycle)) (* pi (wheel-size object))) ;; pi在Common Lisp中已經是一個內置的常量。 ;; 假設我們已經知道了效率值(“efficiency value”)和船槳數大概呈對數關系; ;; 那么效率值的定義應當在構造器/初始化過程中就被完成。 ;; 下面是一個Common Lisp構造實例時初始化實例的例子: (defmethod initialize-instance :after ((object canoe) &rest args) (setf (average-efficiency object) (log (1+ (number-of-rowers object))))) ;; 接著初構造一個實例并檢查平均效率... (average-efficiency (make-instance 'canoe :number-of-rowers 15)) ; => 2.7725887 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 8\. 宏 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 宏可以讓你擴展語法 ;; 例如,Common Lisp并沒有自帶WHILE循環——所以讓我們自己來為他添加一個; ;; 如果按照匯編程序的直覺來看,我們會這樣寫: (defmacro while (condition &body body) "While `condition` is true, `body` is executed. `condition` is tested prior to each execution of `body`" (let ((block-name (gensym))) `(tagbody (unless ,condition (go ,block-name)) (progn ,@body) ,block-name))) ;; 讓我們來看看它的高級版本: (defmacro while (condition &body body) "While `condition` is true, `body` is executed. `condition` is tested prior to each execution of `body`" `(loop while ,condition do (progn ,@body))) ;; 然而,在一個比較現代化的編譯環境下,這樣的WHILE是沒有必要的; ;; LOOP形式的循環和這個WHILE同樣的好,并且更易于閱讀。 ;; 注意反引號'`',逗號','以及'@'這三個符號; ;; 反引號'`'是一種所謂“quasiquote”的引用類型的運算符,有了它,之后的逗號“,”才有意義。 ;; 逗號“,”意味著解除引用(unquote,即開始求值); ;; “@”符號則表示將當前的參數插入到當前整個列表中。 ;;(譯者注:要想真正用好、用對這三個符號,需要下一番功夫) ;;(甚至光看《實用 Common Lisp 編程》中關于宏的介紹都是不夠的) ;;(建議再去讀一讀Paul Graham的兩本著作《ANSI Common Lisp》和《On Lisp》) ;; 函數`gensym`創建一個唯一的符號——這個符號確保不會出現在其他任何地方。 ;; 這樣做是因為,宏是在編譯期展開的 ;; 而在宏中聲明的變量名極有可能和常規代碼中使用的變量名發生沖突。 ;; 可以去《實用 Common Lisp 編程》中閱讀更多有關宏的內容。 ~~~ ## 拓展閱讀 [繼續閱讀《實用 Common Lisp 編程》一書](http://www.gigamonkeys.com/book/) ## 致謝 非常感謝Scheme社區的人們,我基于他們的成果得以迅速的寫出這篇有關Common Lisp的快速入門 同時也感謝 -?[Paul Khuong](https://github.com/pkhuong)?,他提出了很多有用的點評。 ## 譯者寄語 “祝福那些將思想鑲嵌在重重括號之內的人們。”
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看