summaryrefslogtreecommitdiff
path: root/full-parse.rkt
blob: df1118ca9da742dc18d6a5a2fccc09a5a8ab7071 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#lang racket

(provide full-parse)

; parses a function written in mathematical notation to lisp notation
; currently handles (+ - * / ^). It does respect the order of operations
(define (full-parse 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)))

  ; 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) 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)))