(chicken irregex)
(chicken io)
(chicken string)
- mars)
+ srfi-13 mars)
(define (string->prog str)
(let ((idx 0)
(period-irx (irregex "^\\."))
(redcode-irx (irregex "^;redcode\n"))
(name-start-irx (irregex "^;[ \t]*name "))
- (name-irx (irregex "^[a-zA-Z0-9]+"))
+ (name-irx (irregex "^[^\n]*"))
+ (author-start-irx (irregex "^;[ \t]*author "))
+ (author-irx (irregex "^[^\n]*"))
(comment-irx (irregex "^(;[^\n]*)?\n"))
(org-irx (irregex "^ORG"))
(opcode-DAT-irx (irregex "^DAT"))
(mode-post-indirect-A-irx (irregex "^\\}"))
(mode-post-indirect-B-irx (irregex "^>"))
(number-irx (irregex "^(\\+|-)?[0-9]+")))
+
(define (accept-token irx . rest)
(let ((wsmatch (irregex-search whitespace-irx (substring str idx))))
(if wsmatch
(if mandatory
(error "Unexpected token at input string index" idx)
#f))))
+
(define (load-file)
(accept-token redcode-irx #t)
(let loop ((instrs '())
(offset 0)
- (name '()))
+ (name '())
+ (author '()))
(let ((this-line (line)))
(if this-line
(case (car this-line)
- ((name) (loop instrs offset (cdr this-line)))
- ((comment) (loop instrs offset name))
- ((org) (loop instrs (cdr this-line) name))
- ((instr) (loop (cons (cdr this-line) instrs) offset name)))
- (make-prog name (reverse instrs) offset)))))
+ ((name) (loop instrs offset (cdr this-line) author))
+ ((author) (loop instrs offset name (cdr this-line)))
+ ((comment) (loop instrs offset name author))
+ ((org) (loop instrs (cdr this-line) name author))
+ ((instr) (loop (cons (cdr this-line) instrs) offset name author)))
+ (make-prog name author (reverse instrs) offset)))))
+
(define (line)
(or (name-line)
+ (author-line)
(comment-line)
(org-line)
(instruction-line)))
+
(define (name-line)
(if (accept-token name-start-irx)
- (cons 'name (string->symbol (accept-token name-irx #t)))
+ (cons 'name (string-trim (accept-token name-irx #t)))
+ #f))
+
+ (define (author-line)
+ (if (accept-token author-start-irx)
+ (cons 'author (string-trim (accept-token author-irx #t)))
#f))
+
(define (comment-line)
(if (accept-token comment-irx)
'(comment)
#f))
+
(define (org-line)
(if (accept-token org-irx)
(cons 'org (string->number (accept-token number-irx #t)))
#f))
+
(define (instruction-line)
(let ((oc (opcode)))
(if oc
(let ((x (accept-token period-irx #t))
(modif (modifier))
(A-mode (mode))
- (A-num (accept-token number-irx #t))
+ (A-num (string->number (accept-token number-irx #t)))
(y (accept-token comma-irx #t))
(B-mode (mode))
- (B-num (accept-token number-irx #t))
+ (B-num (string->number (accept-token number-irx #t)))
(z (accept-token comment-irx #t)))
(cons 'instr (make-instr oc modif A-mode A-num B-mode B-num)))
#f)))
+
(define (opcode)
(let ((res (or (accept-token opcode-DAT-irx)
(accept-token opcode-MOV-irx)
(accept-token opcode-SPL-irx)
(accept-token opcode-NOP-irx))))
(if res (string->symbol res) #f)))
+
(define (modifier)
(string->symbol
(or (accept-token modifier-AB-irx)
(accept-token modifier-F-irx)
(accept-token modifier-X-irx)
(accept-token modifier-I-irx))))
+
(define (mode)
(or (mode-immediate)
(mode-direct)
(mode-pre-indirect-B)
(mode-post-indirect-A)
(mode-post-indirect-B)))
+
(define (mode-immediate)
(and (accept-token mode-immediate-irx)
'immediate))
+
(define (mode-direct)
(and (accept-token mode-direct-irx)
'direct))
+
(define (mode-indirect-A)
(and (accept-token mode-indirect-A-irx)
'indirect-A))
+
(define (mode-indirect-B)
(and (accept-token mode-indirect-B-irx)
'indirect-B))
+
(define (mode-pre-indirect-A)
(and (accept-token mode-pre-indirect-A-irx)
'pre-indirect-A))
+
(define (mode-pre-indirect-B)
(and (accept-token mode-pre-indirect-B-irx)
'pre-indirect-B))
+
(define (mode-post-indirect-A)
(and (accept-token mode-post-indirect-A-irx)
'post-indirect-A))
+
(define (mode-post-indirect-B)
(and (accept-token mode-post-indirect-B-irx)
'post-indirect-B))
+
(load-file))))