;; Define helper functions
(define (drop-while pred lis)
(if (or (null? lis) (not (pred (car lis))))
lis
(drop-while pred (cdr lis))))
(define (take-while pred lis)
(define (take-while-helper pred lis result)
(if (and (not (null? lis)) (pred (car lis)))
(take-while-helper pred (cdr lis) (cons (car lis) result))
(reverse result)))
(take-while-helper pred lis '()))
(define (char-other? ch)
(not (or (= (char->integer ch) 91)
(= (char->integer ch) 93)
(= (char->integer ch) 40)
(= (char->integer ch) 41)
(= (char->integer ch) 32)
(= (char->integer ch) 10))))
(define (process-other chars)
(and (not (null? chars))
(let* ((token-chars (take-while char-other? chars))
(rest (drop-while char-other? chars)))
(list token-chars rest))))
;; Custom function to check if all elements in a list are characters
(define (all-char? lis)
(if (null? lis)
#t
(and (char? (car lis)) (all-char? (cdr lis)))))
;; Function to tag tokens with their type
(define (tag-token type value)
(list type value))
;; Functions to take and drop elements from the list
(define (take n lis)
(if (or (<= n 0) (null? lis))
'()
(cons (car lis) (take (- n 1) (cdr lis)))))
(define (drop n lis)
(if (or (<= n 0) (null? lis))
lis
(drop (- n 1) (cdr lis))))
;; Functions for Dot Count
(define (process-dots chars)
(let* ((dot-chars (take-while (lambda (ch) (char=? ch (integer->char 46))) chars)) ; char 46 is '.'
(num-dots (length dot-chars))
(rest (drop-while (lambda (ch) (char=? ch (integer->char 46))) chars)))
(list num-dots rest)))
;; Define main tokenize function with integrated new functions
(define (tokenize input)
(let loop ((chars (string->list input)) (tokens '()))
(cond
((null? chars) (reverse tokens)) ; Return the reversed tokens
((char=? (car chars) (integer->char 91)) ; Handle opening bracket [
(loop (cdr chars) (cons (tag-token 'open-bracket "[") tokens)))
((char=? (car chars) (integer->char 93)) ; Handle closing bracket ]
(loop (cdr chars) (cons (tag-token 'close-bracket "]") tokens)))
((char=? (car chars) (integer->char 40)) ; Handle opening parenthesis
(loop (cdr chars) (cons (tag-token 'open-parenthesis "(") tokens)))
((char=? (car chars) (integer->char 41)) ; Handle closing parenthesis
(loop (cdr chars) (cons (tag-token 'close-parenthesis ")") tokens)))
((char=? (car chars) (integer->char 32)) ; Skip spaces
(loop (cdr chars) tokens))
((char=? (car chars) (integer->char 46)) ; Handle dots (.)
(let* ((result (process-dots chars))
(num-dots (car result))
(rest (cadr result)))
(loop rest (cons (tag-token 'dots num-dots) tokens)))) ; Use a tagged list structure
(else
(let* ((result (process-other chars))
(token (car result))
(rest (cadr result)))
(loop rest (cons (tag-token 'other token) tokens)))))) ); End of tokenize function
(define (simplify-for-output x) x)
;; Function to check if a token represents dots
(define (dots? x) (and (pair? x) (pair? (car x))
(eq? 'dots (caar x))))
(define (dot-count x) (cadr x))
;; Function to gather tokens over nested parentheses
(define (gather-tokens tokens)
(define (helper tokens collected depth)
(cond
((null? tokens) (list (reverse collected) tokens))
((and (equal? (car (car tokens)) 'close-parenthesis) (= depth 1))
(list (reverse (cons (car tokens) collected)) (cdr tokens)))
((equal? (car (car tokens)) 'close-parenthesis)
(helper (cdr tokens) (cons (car tokens) collected) (- depth 1)))
((equal? (car (car tokens)) 'open-parenthesis)
(helper (cdr tokens) (cons (car tokens) collected) (+ depth 1)))
(else
(helper (cdr tokens) (cons (car tokens) collected) depth))))
(helper tokens '() 0))
;; Function to gather and tag tokens based on dots
(define (process-final tokens)
(define (process-helper reversed-tokens forward-tail)
(cond
((null? reversed-tokens)
(simplify-for-output forward-tail))
((dots? (car reversed-tokens))
(let* ((count (dot-count (car reversed-tokens)))
(gathered (gather-tokens forward-tail))
(the-tail (cons (tag-token 'final (car gathered)) (cdr gathered))))
(process-helper (cdr reversed-tokens) the-tail)))
(else
(process-helper (cdr reversed-tokens) (cons (car reversed-tokens) forward-tail)))))
(define (process-helperz . args)
(debug 'process-helper args)
(apply process-helper args))
(process-helperz (reverse tokens) '())
'(process-helper (reverse tokens) '()))
;; DEBUG
(define (debug procedure-name args)
(define (debug-helper args)
(if (null? (cdr args))
args
(cons (car args)
(cons '--- (debug-helper (cdr args))))))
(write (cons procedure-name (debug-helper args)))(newline))
;; Example usage
(define input "(define) f g (). 1 2")
;; Tokenize the input
(let ((tokens (tokenize input)))
(write tokens) ; Write the intermediate tokenized output for debugging
(newline)(newline)
(write (process-final tokens))) ; Return the final processed output