diff options
Diffstat (limited to 'math-parser.scm')
-rw-r--r-- | math-parser.scm | 63 |
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))) |