summaryrefslogtreecommitdiff
path: root/math-parser.scm
diff options
context:
space:
mode:
Diffstat (limited to 'math-parser.scm')
-rw-r--r--math-parser.scm63
1 files changed, 63 insertions, 0 deletions
diff --git a/math-parser.scm b/math-parser.scm
new file mode 100644
index 0000000..1048250
--- /dev/null
+++ b/math-parser.scm
@@ -0,0 +1,63 @@
+; parses a function written in mathematical notation to lisp notation
+; currently handles (+ - * / ^). It does respect the order of operations
+(define (parse-math str)
+ (define (get-general expr operator next-operation)
+
+ ; adds a operation to the list of operations
+ ; if it's a number or a single variable then it's just added
+ ; if it's an operation then it's evaluated
+ (define (add-operation-to-list operation seq)
+ (cons (if (= (length operation) 1)
+ (char->wanted (car operation))
+ (next-operation (reverse operation)))
+ seq))
+
+ (define (inner current-term other-terms remaining-expression)
+ (cond
+ [(null? remaining-expression)
+ (add-operation-to-list current-term other-terms)]
+ [(eqv? (car remaining-expression) operator)
+ (inner '()
+ (add-operation-to-list current-term other-terms)
+ (cdr remaining-expression))]
+ [else
+ (inner (cons (car remaining-expression) current-term)
+ other-terms
+ (cdr remaining-expression))]))
+
+
+ (if (not (contains operator expr))
+ (next-operation expr)
+ (cons (char->wanted operator) (reverse (inner '() '() expr)))))
+
+ (define (contains value seq)
+ (memq value seq))
+
+ ; char->number if numerical
+ ; char->symbol otherwise
+ (define (char->wanted c)
+ ((if (char-numeric? c)
+ string->number string->symbol)
+ (string c)))
+
+ ; goes from a list of chars to a number
+ ; returns #f if conversion is not possible
+ (define (make-number expr)
+ (if (list? expr)
+ (string->number (list->string expr))
+ expr))
+
+ ; creates a fucntion for the current operator,
+ ; with a function call for the next operatior as a parameter
+ (define (create-trace expr ops)
+ (lambda (expr)
+ ;(display expr) (newline)
+ (get-general expr (car ops)
+ (if (null? (cdr ops))
+ (lambda (x) (make-number x))
+ (create-trace expr (cdr ops))))))
+
+ ; start the function, with the operations
+ ; in order, from outermost to innermost.
+ (let ((expr (string->list str)))
+ ((create-trace expr '(#\+ #\- #\* #\/ #\^)) expr)))