Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env emacs --script
|
||||
;; -*- mode: emacs-lisp; lexical-binding: t -*-
|
||||
;;> ./arithmetic-evaluation '(1 + 2) * 3'
|
||||
|
||||
(defun advance ()
|
||||
(let ((rtn (buffer-substring-no-properties (point) (match-end 0))))
|
||||
(goto-char (match-end 0))
|
||||
rtn))
|
||||
|
||||
(defvar current-symbol nil)
|
||||
|
||||
(defun next-symbol ()
|
||||
(when (looking-at "[ \t\n]+")
|
||||
(goto-char (match-end 0)))
|
||||
|
||||
(cond
|
||||
((eobp)
|
||||
(setq current-symbol 'eof))
|
||||
((looking-at "[0-9]+")
|
||||
(setq current-symbol (string-to-number (advance))))
|
||||
((looking-at "[-+*/()]")
|
||||
(setq current-symbol (advance)))
|
||||
((looking-at ".")
|
||||
(error "Unknown character '%s'" (advance)))))
|
||||
|
||||
(defun accept (sym)
|
||||
(when (equal sym current-symbol)
|
||||
(next-symbol)
|
||||
t))
|
||||
|
||||
(defun expect (sym)
|
||||
(unless (accept sym)
|
||||
(error "Expected symbol %s, but found %s" sym current-symbol))
|
||||
t)
|
||||
|
||||
(defun p-expression ()
|
||||
" expression = term { ('+' | '-') term } . "
|
||||
(let ((rtn (p-term)))
|
||||
(while (or (equal current-symbol "+") (equal current-symbol "-"))
|
||||
(let ((op current-symbol)
|
||||
(left rtn))
|
||||
(next-symbol)
|
||||
(setq rtn (list op left (p-term)))))
|
||||
rtn))
|
||||
|
||||
(defun p-term ()
|
||||
" term = factor { ('*' | '/') factor } . "
|
||||
(let ((rtn (p-factor)))
|
||||
(while (or (equal current-symbol "*") (equal current-symbol "/"))
|
||||
(let ((op current-symbol)
|
||||
(left rtn))
|
||||
(next-symbol)
|
||||
(setq rtn (list op left (p-factor)))))
|
||||
rtn))
|
||||
|
||||
(defun p-factor ()
|
||||
" factor = constant | variable | '(' expression ')' . "
|
||||
(let (rtn)
|
||||
(cond
|
||||
((numberp current-symbol)
|
||||
(setq rtn current-symbol)
|
||||
(next-symbol))
|
||||
((accept "(")
|
||||
(setq rtn (p-expression))
|
||||
(expect ")"))
|
||||
(t (error "Syntax error")))
|
||||
rtn))
|
||||
|
||||
(defun ast-build (expression)
|
||||
(let (rtn)
|
||||
(with-temp-buffer
|
||||
(insert expression)
|
||||
(goto-char (point-min))
|
||||
(next-symbol)
|
||||
(setq rtn (p-expression))
|
||||
(expect 'eof))
|
||||
rtn))
|
||||
|
||||
(defun ast-eval (v)
|
||||
(pcase v
|
||||
((pred numberp) v)
|
||||
(`("+" ,a ,b) (+ (ast-eval a) (ast-eval b)))
|
||||
(`("-" ,a ,b) (- (ast-eval a) (ast-eval b)))
|
||||
(`("*" ,a ,b) (* (ast-eval a) (ast-eval b)))
|
||||
(`("/" ,a ,b) (/ (ast-eval a) (float (ast-eval b))))
|
||||
(_ (error "Unknown value %s" v))))
|
||||
|
||||
(dolist (arg command-line-args-left)
|
||||
(let ((ast (ast-build arg)))
|
||||
(princ (format " ast = %s\n" ast))
|
||||
(princ (format " value = %s\n" (ast-eval ast)))
|
||||
(terpri)))
|
||||
(setq command-line-args-left nil)
|
||||
Loading…
Add table
Add a link
Reference in a new issue