Created
March 26, 2011 08:19
Revisions
-
zeptometer revised this gist
Mar 28, 2011 . 1 changed file with 92 additions and 95 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,15 +2,12 @@ (:use :cl) (:export #:add-operator #:add-infix-function #:install-default-operators-and-infix-functions)) (in-package :infix) (defconstant default-operators '((1 ** expt :right) (2 *) (2 /) (2 % mod) @@ -29,9 +26,9 @@ (9 \| logior) (10 && and) (11 || or) (12 = setf :right) (12 += incf :right) (12 -= decf :right))) (defconstant default-infix-functions '((sqrt 1) @@ -41,70 +38,68 @@ (log 2) (loge 1 log) (log10 1 (lambda (x) (log x 10))) (! 1 not) (~ 1 lognot))) (defclass infix-function () ((type :initarg :type :accessor infix-function-type) (clname :initarg :clname :accessor infix-function-clname) (numarg :initarg :numarg :accessor infix-function-numarg) (priority :initarg :priority :initform 7 :accessor infix-function-priority) (direction :initarg :direction :accessor infix-function-direction))) (defconstant leastpriority 20) (defvar *operators-priority* (make-hash-table :test #'equal) "優先順位毎の演算子") (defvar *operators* (make-hash-table) "演算子と算術関数のデータ") (defun single (x) (and (consp x) (null (cdr x)))) (defun operatorp (op) (multiple-value-bind (op* win) (gethash op *operators*) (and win (eq (infix-function-type op*) :operator)))) (defun ifunctionp (op) (multiple-value-bind (op* win) (gethash op *operators*) (and win (eq (infix-function-type op*) :ifunction)))) (defun getnumarg (op) (infix-function-numarg (gethash op *operators*))) (defun getclname (op) (infix-function-clname (gethash op *operators*))) (defun apply-ifunction (exp) "算術関数を普通のポーランド記法の形にする (apply-ifunction '(sqrt a + sin cos b)) -> '((sqrt a) + (sin (cos b)))" (let ((stack nil)) (dolist (i (nreverse exp)) (if (ifunctionp i) (let ((polish)) (push (getclname i) polish) (dotimes (j (getnumarg i)) (push (pop stack) polish)) (push (nreverse polish) stack)) (push i stack))) stack)) (defun devide-infix (exp ops direction) "ops中の演算子でexpを分割する。directionの結合を用いる。 三つの値を返す。 1: 演算子 2: 演算子より前の式 @@ -115,31 +110,32 @@ -> - (1 + 2 * 3) (3)" (labels ((rec (exp ops* stack) (if (member (car exp) ops*) (ecase direction (:left (values (car exp) (reverse (cdr exp)) stack)) (:right (values (car exp) (reverse stack) (cdr exp)))) (rec (cdr exp) ops* (cons (car exp) stack))))) (ecase direction (:left (rec (reverse exp) ops nil)) (:right (rec exp ops nil))))) (defun infix-polish (exp) "中間記法の式を普通のS式(ポーランド記法)に変換する。" (if (single exp) (car exp) (do ((priority 20 (- priority (ecase dir (:left 0) (:right 1)))) (dir :left (ecase dir (:left :right) (:right :left)))) ((zerop priority) nil) (let ((ops (gethash `(,priority ,dir) *operators-priority*))) (when (some (lambda (op) (member op exp)) ops) (multiple-value-bind (op bef af) (devide-infix exp ops dir) (return (list (getclname op) (infix-polish bef) (infix-polish af))))))))) (defmacro infix (&rest exp) "中間記法用マクロ。 applyarしてinfix-polishする" (infix-polish (apply-ifunction exp))) ;{}で中間記法を表す (set-macro-character #\} (get-macro-character #\))) @@ -149,39 +145,40 @@ (declare (ignore char)) (cons 'infix (read-delimited-list #\} stream t)))) (defun add-operator (priority op &optional clname (direction :left)) (unless clname (setf clname op)) (setf (gethash op *operators*) (make-instance 'infix-function :type :operator :clname clname :numarg 2 :priority priority :direction direction)) (push op (gethash `(,priority ,direction) *operators-priority*))) (defun add-ifunction (fun numarg &optional clname) (unless clname (setf clname fun)) (setf (gethash fun *operators*) (make-instance 'infix-function :type :ifunction :clname clname :numarg numarg :priority nil :direction nil))) (defun initialize () "演算子及び算術関数に関するデータを初期化する" (clrhash *operators-priority*) (clrhash *operators*)) (defun install-default-operators-and-infix-functions () (initialize) (mapcar #'(lambda (x) (apply #'add-operator x)) default-operators) (mapcar #'(lambda (x) (apply #'add-ifunction x)) default-infix-functions) t) (install-default-operators-and-infix-functions) -
zeptometer revised this gist
Mar 28, 2011 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,6 +2,7 @@ (:use :cl) (:export #:add-operator #:add-infix-function #:initialize #:install-default-operators-and-infix-functions)) (in-package :infix) -
zeptometer revised this gist
Mar 28, 2011 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -165,13 +165,13 @@ (push (cons fun cl-name) arfunction-clfunction)) (defun initialize () (setf operators nil) (setf operator-clfunction nil) (setf arfunction nil) (setf arfunction-clfunction nil) (dotimes (i leastpriority) (push (list 'right) operators) (push (list 'left) operators))) (defun install-default-operators-and-infix-functions () "デフォルトの演算子と算術関数をインストールする" -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -149,6 +149,7 @@ (cons 'infix (read-delimited-list #\} stream t)))) (defun add-operator (priority op &optional cl-name (direction 'left)) "演算子を追加" (unless cl-name (setq cl-name op)) (push op (cdr (nth (ecase direction @@ -157,6 +158,7 @@ (push (cons op cl-name) operator-clfunction)) (defun add-infix-function (fun num &optional cl-name) "算術関数を追加" (unless cl-name (setf cl-name fun)) (push (cons fun num) arfunction) @@ -172,6 +174,7 @@ (push 'right (nth (1+ (* 2 i)) operators)))) (defun install-default-operators-and-infix-functions () "デフォルトの演算子と算術関数をインストールする" (initialize) (mapcar #'(lambda (x) (apply #'add-operator x)) default-operators) (mapcar #'(lambda (x) (apply #'add-infix-function x)) default-infix-functions) -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -49,8 +49,8 @@ (defvar operators nil "演算子。優先順位の低い順にグループ分け。") (defvar operator-clfunction nil "演算子と関数の対応表") (defvar arfunction nil "算術関数とその引数の一覧") (defvar arfunction-clfunction nil "算術関数とCL関数の対応表") (defvar stack nil) @@ -177,6 +177,7 @@ (mapcar #'(lambda (x) (apply #'add-infix-function x)) default-infix-functions) t) ;ロード時に読み込む (install-default-operators-and-infix-functions) -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 97 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,12 +1,53 @@ (defpackage :infix (:use :cl) (:export #:add-operator #:add-infix-function #:install-default-operators-and-infix-functions)) (in-package :infix) (defconstant leastpriority 20) (defconstant default-operators '((1 ** expt right) (2 *) (2 /) (2 % mod) (3 +) (3 -) (4 >> (lambda (x y) (ash x (- y)))) (4 << ash) (5 <) (5 <=) (5 >) (5 >=) (6 == =) (6 != (lambda (x y) (not (= x y)))) (7 & logand) (8 ^ logxor) (9 \| logior) (10 && and) (11 || or) (12 = setf right) (12 += incf right) (12 -= decf right))) (defconstant default-infix-functions '((sqrt 1) (sin 1) (cos 1) (tan 1) (log 2) (loge 1 log) (log10 1 (lambda (x) (log x 10))) (+ 1) (- 1) (! 1 not) (~ 1 lognot))) (defvar operators nil "演算子。優先順位の低い順にグループ分け。") (defvar operator-clfunction nil "演算子と関数の対応表") (defvar arfunction '((sqrt 1) (sin 1) (cos 1) (tan 1) (log 2) (+ 1) (- 1) (! 1) (~ 1)) "算術関数とその引数の一覧") (defvar arfunction-clfunction '((sqrt sqrt) (sin sin) (cos cos) (tan tan) (log log) (+ +) (- -) (! not) (~ lognot)) "算術関数とCL関数の対応表") @@ -20,30 +61,30 @@ (some (lambda (x) (member op (cdr x))) operators)) (defun arfunctionp (ar) (cdr (assoc ar arfunction))) (defun op-cl (op) "opに対応するCL関数を返す" (cdr (assoc op operator-clfunction))) (defun ar-cl (ar) (cdr (assoc ar arfunction-clfunction))) (defun applyar (exp) "算術関数を普通のポーランド記法の形にする (applyar '(sqrt a + sin cos b)) -> '((sqrt a) + (sin (cos b)))" (labels ((rec (exp loaded) (cond ((null exp) (reverse loaded)) ((single exp) (rec nil (cons (car exp)loaded))) ((arfunctionp (car exp)) (multiple-value-bind (exp* rest) (loadar exp) (rec (cons exp* rest) loaded))) ((and (not (arfunctionp (car exp))) (operatorp (cadr exp))) (rec (cddr exp) (list* (cadr exp) (car exp) loaded)))))) (rec exp nil))) (defun loadar (exp) @@ -74,15 +115,15 @@ (1 + 2 * 3) (3)" (destructuring-bind (direction &rest ops*) ops (labels ((rec (exp ops* stack) (if (member (car exp) ops*) (ecase direction (left (values (car exp) (reverse (cdr exp)) stack)) (right (values (car exp) (reverse stack) (cdr exp)))) (rec (cdr exp) ops* (cons (car exp) stack))))) (ecase direction (left (rec (reverse exp) ops* nil)) (right (rec exp ops* nil)))))) (defun infix-polish (exp) "中間記法の式を普通のS式(ポーランド記法)に変換する。" @@ -107,3 +148,35 @@ (declare (ignore char)) (cons 'infix (read-delimited-list #\} stream t)))) (defun add-operator (priority op &optional cl-name (direction 'left)) (unless cl-name (setq cl-name op)) (push op (cdr (nth (ecase direction (left (- (* 2 leastpriority) (* 2 priority))) (right (- (* 2 leastpriority) (1+ (* 2 priority))))) operators))) (push (cons op cl-name) operator-clfunction)) (defun add-infix-function (fun num &optional cl-name) (unless cl-name (setf cl-name fun)) (push (cons fun num) arfunction) (push (cons fun cl-name) arfunction-clfunction)) (defun initialize () (setf operators (make-list (* 2 leastpriority) :initial-element nil)) (setf operator-clfunction nil) (setf arfunction nil) (setf arfunction-clfunction nil) (dotimes (i leastpriority) (push 'left (nth (* 2 i) operators)) (push 'right (nth (1+ (* 2 i)) operators)))) (defun install-default-operators-and-infix-functions () (initialize) (mapcar #'(lambda (x) (apply #'add-operator x)) default-operators) (mapcar #'(lambda (x) (apply #'add-infix-function x)) default-infix-functions) t) (install-default-operators-and-infix-functions) -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,11 +5,11 @@ #:arfunction #:arfunction-clfunction)) (defvar operators '((right = += -=) (left ||) (left &&) (left \|) (left ^) (left &) (left == !=) (left < <= > >=) (left >> <<) (left + -) (left * / %) (right **)) "演算子。優先順位の低い順にグループ分け。") (defvar operator-clfunction '((= setf) (+= incf) (-= decf) (|| or) (&& and) (\| logior) (^ logor) (& logand) (== =) (!= (lambda (x y) (not (= x y)))) (< <) (<= <=) (> >) (>= >=) (>> (lambda (x y) (ash x (- y)))) (<< ash) (+ +) (- -) (* *) (/ /) (% mod) (** expt)) "演算子と関数の対応表") (defvar arfunction '((sqrt 1) (sin 1) (cos 1) (tan 1) (log 2) (+ 1) (- 1) (! 1) (~ 1)) "算術関数とその引数の一覧") (defvar arfunction-clfunction '((sqrt sqrt) (sin sin) (cos cos) (tan tan) (log log) (+ +) (- -) (! not) (~ lognot)) "算術関数とCL関数の対応表") (defvar stack nil) -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 16 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,8 +5,8 @@ #:arfunction #:arfunction-clfunction)) (defvar operators '((left or) (left and) (left == !=) (left < <= > >=) (left + -) (left * / %) (right **)) "演算子。優先順位の低い順にグループ分け。") (defvar operator-clfunction '((or or) (and and) (== =) (!= (lambda (x y) (not (= x y)))) (< <) (<= <=) (> >) (>= >=) (+ +) (- -) (* *) (/ /) (% mod) (** expt)) "演算子と関数の対応表") (defvar arfunction '((sqrt 1) (sin 1) (cos 1) (tan 1) (log 2) (+ 1) (- 1)) "算術関数とその引数の一覧") (defvar arfunction-clfunction '((sqrt sqrt) (sin sin) (cos cos) (tan tan) (log log) (+ +) (- -)) "算術関数とCL関数の対応表") @@ -17,7 +17,7 @@ (and (consp x) (null (cdr x)))) (defun operatorp (op) (some (lambda (x) (member op (cdr x))) operators)) (defun arfunctionp (ar) (cadr (assoc ar arfunction))) @@ -62,30 +62,34 @@ (values (reverse (pop stack)) rest))) (defun devide-infix (exp ops) "(cdr ops)中の演算子でexpを分割する。(car ops)にある結合を用いる。 三つの値を返す。 1: 演算子 2: 演算子より前の式 3: 演算子より後の式 Example: (devide-infix '(1 + 2 * 3 - 3) '(left + -)) -> - (1 + 2 * 3) (3)" (destructuring-bind (direction &rest ops*) ops (labels ((rec (exp ops* stack) (if (member (car exp) ops*) (ecase direction (left (values (car exp) (reverse (cdr exp)) stack)) (right (values (car exp) (reverse stack) (cdr exp)))) (rec (cdr exp) ops* (cons (car exp) stack))))) (ecase direction (left (rec (reverse exp) ops* nil)) (right (rec exp ops* nil)))))) (defun infix-polish (exp) "中間記法の式を普通のS式(ポーランド記法)に変換する。" (if (single exp) (car exp) (dolist (ops operators) (when (some (lambda (op) (member op exp)) (cdr ops)) (multiple-value-bind (op bef af) (devide-infix exp ops) (return (list (op-cl op) (infix-polish bef) (infix-polish af)))))))) -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 11 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,7 +30,9 @@ (cadr (assoc ar arfunction-clfunction))) (defun applyar (exp) "算術関数を普通のポーランド記法の形にする (applyar '(sqrt a + sin cos b)) -> '((sqrt a) + (sin (cos b)))" (labels ((rec (exp loaded) (cond ((null exp) (reverse loaded)) @@ -45,6 +47,10 @@ (rec exp nil))) (defun loadar (exp) "applyar補助関数 (loadar '(sqrt a + sin cos b)) -> (sqrt a) (+ sin cos b)" (destructuring-bind (ar &rest rest) exp (push (list (ar-cl ar)) stack) (dotimes (i (arfunctionp ar)) @@ -84,9 +90,12 @@ (return (list (op-cl op) (infix-polish bef) (infix-polish af)))))))) (defmacro infix (&rest exp) "中間記法用マクロ。 applyarしてinfix-polishする" (infix-polish (applyar exp))) ;{}で中間記法を表す (set-macro-character #\} (get-macro-character #\))) (set-macro-character #\{ -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,6 +30,7 @@ (cadr (assoc ar arfunction-clfunction))) (defun applyar (exp) "算術関数を普通のポーランド記法の形にする" (labels ((rec (exp loaded) (cond ((null exp) (reverse loaded)) -
zeptometer revised this gist
Mar 27, 2011 . 1 changed file with 47 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,23 +1,58 @@ (defpackage :infix (:use :cl) (:export #:operators #:operator-clfunction #:arfunction #:arfunction-clfunction)) (defvar operators '((or) (and) (== !=) (< <= > >=) (+ -) (* / %) (^)) "演算子。優先順位の低い順にグループ分け。") (defvar operator-clfunction '((or or) (and and) (== =) (!= (lambda (x y) (not (= x y)))) (< <) (<= <=) (> >) (>= >=) (+ +) (- -) (* *) (/ /) (% mod) (^ expt)) "演算子と関数の対応表") (defvar arfunction '((sqrt 1) (sin 1) (cos 1) (tan 1) (log 2) (+ 1) (- 1)) "算術関数とその引数の一覧") (defvar arfunction-clfunction '((sqrt sqrt) (sin sin) (cos cos) (tan tan) (log log) (+ +) (- -)) "算術関数とCL関数の対応表") (defvar stack nil) (defun single (x) (and (consp x) (null (cdr x)))) (defun operatorp (op) (some (lambda (x) (member op x)) operators)) (defun arfunctionp (ar) (cadr (assoc ar arfunction))) (defun op-cl (op) "opに対応するCL関数を返す" (cadr (assoc op operator-clfunction))) (defun ar-cl (ar) (cadr (assoc ar arfunction-clfunction))) (defun applyar (exp) (labels ((rec (exp loaded) (cond ((null exp) (reverse loaded)) ((single exp) (rec nil (cons (car exp)loaded))) ((arfunctionp (car exp)) (multiple-value-bind (exp* rest) (loadar exp) (rec (cons exp* rest) loaded))) ((and (not (arfunctionp (car exp))) (operatorp (cadr exp))) (rec (cddr exp) (list* (cadr exp) (car exp) loaded)))))) (rec exp nil))) (defun loadar (exp) (destructuring-bind (ar &rest rest) exp (push (list (ar-cl ar)) stack) (dotimes (i (arfunctionp ar)) (if (arfunctionp (car rest)) (multiple-value-bind (exp* rest*) (loadar rest) (push exp* (car stack)) (setf rest rest*)) (push (pop rest) (car stack)))) (values (reverse (pop stack)) rest))) (defun devide-infix (exp ops) "ops中の演算子でexpを分割する。複数出てくる場合は最後のものを。 @@ -49,7 +84,7 @@ (defmacro infix (&rest exp) "中間記法用マクロ" (infix-polish (applyar exp))) (set-macro-character #\} (get-macro-character #\))) @@ -58,15 +93,3 @@ (declare (ignore char)) (cons 'infix (read-delimited-list #\} stream t)))) -
zeptometer revised this gist
Mar 26, 2011 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -67,6 +67,6 @@ ;(defun test (n) ; {n * (1+ n) / 2}) ;(defun test2 (a d n) ; {n * {2 * a + {n - 1} * d} / 2}) -
zeptometer revised this gist
Mar 26, 2011 . 1 changed file with 28 additions and 18 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,19 +1,19 @@ (defvar operators '((or) (and) (== !=) (< <= > >=) (+ -) (* / %) (^)) "演算子。優先順位の低い順にグループ分け。") (defvar clfunction '((or or) (and and) (== =) (!= (lambda (x y) (not (= x y)))) (< <) (<= <=) (> >) (>= >=) (+ +) (- -) (* *) (/ /) (% mod) (^ expt)) "演算子と関数の対応表") (defun single (x) (and (consp x) (null (cdr x)))) ;(defun operatorp (op) ; (some (lambda (x) (member op x)) operators)) ;(defun infixp (exp) ; "expが中間記法の時、tを返す" ; (and (consp exp) ; (not (operatorp (car exp))) ; (operatorp (cadr exp)) ; (or (infixp (cddr exp)) ; (single (cddr exp))))) (defun op-cl (op) "opに対応するCL関数を返す" @@ -40,15 +40,12 @@ (defun infix-polish (exp) "中間記法の式を普通のS式(ポーランド記法)に変換する。" (if (single exp) (car exp) (dolist (ops operators) (when (some (lambda (op) (member op exp)) ops) (multiple-value-bind (op bef af) (devide-infix exp ops) (return (list (op-cl op) (infix-polish bef) (infix-polish af)))))))) (defmacro infix (&rest exp) "中間記法用マクロ" @@ -59,4 +56,17 @@ (set-macro-character #\{ (lambda (stream char) (declare (ignore char)) (cons 'infix (read-delimited-list #\} stream t)))) ;(defun niji (a b c) ; {{(- b) + (sqrt {b ^ 2 - 4 * a * c})} / {2 * a}}) ;(defun niji* (a b c) ; {{- b + sqrt {b ^ 2 - 4 * a * c}} / {2 * a}}) ;(defun test (n) ; {n * (1+ n) / 2}) (defun test2 (a d n) {n * {2 * a + {n - 1} * d} / 2}) -
zeptometer renamed this gist
Mar 26, 2011 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
zeptometer renamed this gist
Mar 26, 2011 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
zeptometer created this gist
Mar 26, 2011 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,62 @@ (defvar operators '( (||) (&&) (^) (&) (== !=) (< <= > >=) (>>> >> <<) (+ -) (* / %)) "演算子。優先順位の低い順にグループ分け。") (defvar clfunction '((|| or) (&& and) (^ logxor) (& logand) (== =) (!= (lambda (x y) (not (= x y)))) (< <) (<= <=) (> >) (>= >=) (>>> (lambda (x y) (ash x (- y))))(>> (lambda (x y) (lsh x (- y)))) (<< lsh) (+ +) (- -) (* *) (/ /) (% mod) (^ expt)) "演算子と関数の対応表") (defun single (x) (and (consp x) (null (cdr x)))) (defun operatorp (op) (some (lambda (x) (member op x)) operators)) (defun infixp (exp) "expが中間記法の時、tを返す" (and (consp exp) (not (operatorp (car exp))) (operatorp (cadr exp)) (or (infixp (cddr exp)) (single (cddr exp))))) (defun op-cl (op) "opに対応するCL関数を返す" (cadr (assoc op clfunction))) (defun devide-infix (exp ops) "ops中の演算子でexpを分割する。複数出てくる場合は最後のものを。 三つの値を返す。 1: 演算子 2: 演算子より前の式 3: 演算子より後の式 Example: (devide-infix '(1 + 2 * 3 - 3) '(+ -)) -> - (1 + 2 * 3) (3)" (labels ((rec (exp ops after) (if (member (car exp) ops) (values (car exp) (reverse (cdr exp)) after) (rec (cdr exp) ops (cons (car exp) after))))) (if (some (lambda (x) (member x exp)) ops) (rec (reverse exp) ops nil)))) (defun infix-polish (exp) "中間記法の式を普通のS式(ポーランド記法)に変換する。" (if (infixp exp) (dolist (ops operators) (when (some (lambda (op) (member op exp)) ops) (multiple-value-bind (op bef af) (devide-infix exp ops) (return (list (op-cl op) (infix-polish bef) (infix-polish af)))))) (let ((x (car exp))) (if (infixp x) (infix-polish x) x)))) (defmacro infix (&rest exp) "中間記法用マクロ" (infix-polish exp)) (set-macro-character #\} (get-macro-character #\))) (set-macro-character #\{ (lambda (stream char) (declare (ignore char)) (cons 'infix (read-delimited-list #\} stream t))))