(define newtemp (let ((x -1)) (lambda () (set! x (+ x 1)) (concatenate-symbol 'tmp- x)))) (define newlabel (let ((x -1)) (lambda () (set! x (+ x 1)) (concatenate-symbol 'lab- x)))) (define (filter pred lst) (if (null? lst) '() (if (pred (car lst)) (cons (car lst) (filter pred (cdr lst))) (filter pred (cdr lst))))) (define (delete elem lst) (filter (lambda (el) (not (equal? el elem))) lst)) (define-record-type entry :entry (make-entry name class type value) entry? (name entry.name entry.name!) (class entry.class entry.class!) (type entry.type entry.type!) (value entry.value entry.value!)) (define-record-discloser :entry (lambda (p) `(entry ,(entry.name p) ,(entry.class p) ,(entry.type p) ,(entry.value p)))) (define (get-attribute attr entry) (case attr ((name) (entry.name entry)) ((class) (entry.class entry)) ((type) (entry.type entry)) ((value) (entry.value entry)) (else (error "get-attribute: unknown attribute")))) (define (set-attribute! attr val entry) (case attr ((name) (entry.name! entry val)) ((class) (entry.class! entry val)) ((type) (entry.type! entry val)) ((value) (entry.value! entry val)) (else (error "set-attribute!: unknown attribute")))) (define (make-empty-entry) (make-entry 'dummy 'dummy 'dummy 'dummy)) (define-record-type symbol-table :symbol-table (make-symbol-table parent childs entries) symbol-table? (parent symbol-table.parent symbol-table.parent!) (childs symbol-table.childs symbol-table.childs!) (entries symbol-table.entries symbol-table.entries!)) (define-record-discloser :symbol-table (lambda (p) `(symbol-table ,(symbol-table.childs p) ,(symbol-table.entries p)))) (define (new-symtab parent-symtab) (let ((child-symtab (make-symbol-table parent-symtab '() '()))) (if (symbol-table? parent-symtab) (let ((childs (symbol-table.childs parent-symtab))) (symbol-table.childs! parent-symtab (cons child-symtab childs)) child-symtab) child-symtab))) (define (delete-symtab symtab) (let ((parent (symbol-table.parent symtab))) (and (symbol-table? parent) (let ((childs (symbol-table.childs parent))) (symbol-table.childs! parent (delete symtab childs)))))) (define (insert-sym symtab symbol) (let* ((entries (symbol-table.entries symtab)) (pair (assoc symbol entries))) (if pair #f (begin (symbol-table.entries! symtab (cons (cons symbol (make-empty-entry)) entries)) #t)))) (define (locate-sym symtab symbol) (assoc symbol (symbol-table.entries symtab))) (define (get-sym-attr symtab symbol attr) (let ((sym-entry (locate-sym symtab symbol))) (if sym-entry (get-attribute attr (cdr sym-entry)) (error "get-sym-attr: symbol not found")))) (define (set-symattr! symtab symbol attr value) (let ((sym-entry (locate-sym symtab symbol))) (if sym-entry (set-attribute! attr value (cdr sym-entry)) (error "set-sym-attr!: symbol not found")))) (define (set-symentry! symtab symbol entry) (let ((sym-entry (locate-sym symtab symbol))) (if sym-entry (set-cdr! sym-entry entry) (error "set-symentry!: symbol not found"))))