Victor Fors 2 år sedan
förälder
incheckning
b35a815aa3
1 ändrade filer med 157 tillägg och 21 borttagningar
  1. +157
    -21
      kekkonen.scm

+ 157
- 21
kekkonen.scm Visa fil

@@ -5,6 +5,8 @@
(import srfi-13) (import srfi-13)
(import matchable) (import matchable)
(import fmt) (import fmt)
(import fmt-color)
(import fmt-unicode)
(import ansi-escape-sequences) (import ansi-escape-sequences)
(import (chicken file)) (import (chicken file))
(import breadline) (import breadline)
@@ -16,6 +18,18 @@
(satisfies (lambda (y) (satisfies (lambda (y)
(not (eqv? x y))))) (not (eqv? x y)))))


(define (curry fn a)
(lambda (b)
(fn a b)))

(define (applied fn)
(curry apply fn))

(define-syntax thunk
(syntax-rules ()
((_ exp ...)
(lambda () exp ...))))

(define parse-whitespace (define parse-whitespace
(one-or-more (is #\space))) (one-or-more (is #\space)))


@@ -29,7 +43,7 @@
(char-set-union +letter-char-set+ (string->char-set "-0123456789"))) (char-set-union +letter-char-set+ (string->char-set "-0123456789")))


(define parse-symbol (define parse-symbol
(lift (compose string->symbol string-downcase list->string (cut apply append <>))
(lift (compose string->symbol string-downcase list->string (applied append))
(sequence (lift list (in +letter-char-set+)) (zero-or-more (in +symbol-char-set+))))) (sequence (lift list (in +letter-char-set+)) (zero-or-more (in +symbol-char-set+)))))


(define parse-number (define parse-number
@@ -67,11 +81,15 @@
(compose (just newline) display)) (compose (just newline) display))


(define (display-lines ln) (define (display-lines ln)
(perhaps (cut map display-newline <>) ln))
(perhaps (curry map display-newline) ln))


(define (parse-input) (define (parse-input)
(parse (completely-parse parse-statement) (read-line))) (parse (completely-parse parse-statement) (read-line)))


(define parse-formatter
(recursive-parser (one-or-more (any-of (followed-by-consuming (char-seq "<b>") (lift fmt-bold parser))
(is-not #\<)))))

(define (type-of elem) (define (type-of elem)
(cond ((pair? elem) 'pair) (cond ((pair? elem) 'pair)
((symbol? elem) 'symbol) ((symbol? elem) 'symbol)
@@ -161,10 +179,19 @@
(loop (cdr kv)))))) (loop (cdr kv))))))


(define (database-save filename) (define (database-save filename)
(with-output-to-file filename (cut write *database*)))
(with-output-to-file filename (thunk (write *database*))))


(define (database-load filename) (define (database-load filename)
(with-input-from-file filename (lambda () (set! *database* (car (read-list))))))
(with-input-from-file filename (thunk (set! *database* (car (read-list))))))

(define (database-remove name)
(let loop ((kv *database*))
(if (null? kv)
'()
(if (equal? name (caar kv))
(cdr kv)
(cons (car kv) (loop (cdr kv)))))))



(define (get-all-objects) (define (get-all-objects)
(map car *database*)) (map car *database*))
@@ -227,7 +254,7 @@
(define (remove-alias object alias) (define (remove-alias object alias)
(let ((aliases (get-aliases object))) (let ((aliases (get-aliases object)))
(if (member alias aliases) (if (member alias aliases)
(set-aliases object (remove (cut eq? alias <>) aliases)))))
(set-aliases object (remove (curry eq? alias) aliases)))))


(define (set-hidden object value) (define (set-hidden object value)
(database-set object 'hidden value)) (database-set object 'hidden value))
@@ -282,24 +309,116 @@
(if (not (member object contents)) (if (not (member object contents))
(begin (begin
(database-set container 'contents (cons object contents)) (database-set container 'contents (cons object contents))
(database-set prev-container 'contents (remove (cut eq? object <>) (get-contents prev-container))))))))
(database-set prev-container 'contents (remove (curry eq? object) (get-contents prev-container))))))))


;; Determine the objects visible to a source object, zork-style ;; Determine the objects visible to a source object, zork-style
(define (visible-objects source) (define (visible-objects source)
(let ((result (get-container source))) (let ((result (get-container source)))
(if (and result (object-exists? result))
(cons (get-container source) (get-contents (get-container source)))
(error "Tried to determine visible objects for object without a container."))))
(if (and result (object-exists? result))
(cons (get-container source) (get-contents (get-container source)))
(error "Tried to determine visible objects for object without a container."))))

(define (any-or fn ln thunk)
(let loop ((ln ln))
(if (null? ln)
(thunk)
(let ((result (fn (car ln))))
(if result
result
(loop (cdr ln)))))))

(define (lisp body environments exit)
(define (eval body)
(lisp body environments exit))
(define (reference symbol)
(cdr (any-or (curry assoc symbol) environments (exit (string-append "Undefined reference: " (symbol->string symbol))))))
; (define (apply function function-args)
; (if
(if (atom? body)
(if (symbol? body)
(reference body)
body)
(let ((function-name (car body))
(function-args (cdr body)))
(if (symbol? function-name)
(case function-name
((test) (show "test function called"))
((if) (match function-args
((e x y) (if (eval e)
(eval x)
(eval y)))
(_ (exit "malformed if expression"))))
((quote) (match function-args
((v) v)
(_ (exit "malformed quote expression"))))
((cons) (match function-args
((a b) (cons (eval a) (eval b)))
(_ (exit "malformed cons expression"))))
((car) (match function-args
((a) (let ((ae (eval a)))
(if (atom? ae)
(exit "tried to take car of atom")
(car (eval a)))))
(_ (exit "malformed car expression"))))
((cdr) (match function-args
((a) (cdr (eval a)))))
((atom) (match function-args
((a) (atom? (eval a)))
(_ (exit "malformed atom expression"))))
((eq) (match function-args
((a b) (equal? (eval a) (eval b)))
(_ (exit "malformed eval expression"))))
; ((set) (match function-args
; ((a b) (if (
((lambda) (match function-args
((args exp . exps)
(if (and (list? args) (every symbol? args))
(cons args (cons exp exps))
(exit "malformed lambda expression")))
(_ (exit "malformed lambda expression"))))
(else (let ((function (reference function-name environments)))
(let ((function-arguments (car function))
(argument-values (cdr body))
(function-body (cddr function)))
(lisp function-body (cons (if (= (length function-arguments) (length argument-values))
(map cons function-arguments (map eval argument-values))
(exit "Wrong number of arguments to function")) environments exit))))))
(exit "attempt to call atom")))))

(define (run-lisp body)
(call/cc (lambda (exit)
(cons #t (lisp body '(()) (compose exit (curry cons #f)))))))
;; (if (and (list function)
;; (>= (length function) 2)
;; (list function-arguments)
;; (every symbol? (car function)))

(define +script-primitives+
`((if . ,(lambda (condition body1 body2)
(script (if (script condition)
body1
body2))))
(eq . ,(lambda (a b)
(equals? (script a) (script b))))
(and . ,(lambda (a b)
(and (script a) (script b))))
(or . ,(lambda (a b)
(or (script a) (script b))))
(not . ,(lambda (a)
(not (script a))))))


(define (print-room-description room) (define (print-room-description room)
(newline) (newline)
(display (set-text '(bold) (get-name room))) (display (set-text '(bold) (get-name room)))
(if (devmode-enabled?) (display (set-text '(bold fg-green) (string-append " [" (symbol->string room) "]"))))
(newline) (newline)
(display " ") (display " ")
(fmt #t (dsp (wrap-lines (get-description room)))) (fmt #t (dsp (wrap-lines (get-description room))))
(newline) (newline)
(display "You see: ") (display "You see: ")
(map (lambda (n) (if (not (get-hidden n)) (begin (display (get-name n)) (display " ")))) (remove (cut eq? 'you <>) (get-contents room)))
(map (lambda (n) (if (not (get-hidden n)) (begin (display (get-name n)) (display " ") (if (devmode-enabled?) (begin (display (set-text '(bold fg-green) (string-append "[" (symbol->string n) "] ")))))))) (remove (curry eq? 'you) (get-contents room)))
(newline)) (newline))


(define (do-command-enter tag) (define (do-command-enter tag)
@@ -407,11 +526,8 @@
(define (do-command-describe tag description) (define (do-command-describe tag description)
(do-setter-command tag description string? set-description)) (do-setter-command tag description string? set-description))


(define +object-flags+
'(fixed hidden))

(define (do-command-flag tag flag) (define (do-command-flag tag flag)
(if (not (and (symbol? tag) (symbol? flag) (member flag +object-flags+)))
(if (not (and (symbol? tag) (symbol? flag)))
(show "I didn't quite understand that.") (show "I didn't quite understand that.")
(let ((object (match-object tag (visible-objects 'you)))) (let ((object (match-object tag (visible-objects 'you))))
(if (not object) (if (not object)
@@ -419,10 +535,11 @@
(begin (begin
(case flag (case flag
((fixed) (set-fixed object #t)) ((fixed) (set-fixed object #t))
((hidden) (set-hidden object #t))))))))
((hidden) (set-hidden object #t))
(else (show "Invalid flag name."))))))))


(define (do-command-unflag tag flag) (define (do-command-unflag tag flag)
(if (not (and (symbol? tag) (symbol? flag) (member flag +object-flags+)))
(if (not (and (symbol? tag) (symbol? flag)))
(show "I didn't quite understand that.") (show "I didn't quite understand that.")
(let ((object (match-object tag (visible-objects 'you)))) (let ((object (match-object tag (visible-objects 'you))))
(if (not object) (if (not object)
@@ -430,7 +547,8 @@
(begin (begin
(case flag (case flag
((fixed) (set-fixed object #f)) ((fixed) (set-fixed object #f))
((hidden) (set-hidden object #f))))))))
((hidden) (set-hidden object #f))
(else (show "Invalid flag name."))))))))


(define (do-command-alias tag alias) (define (do-command-alias tag alias)
(if (not (and (symbol? tag) (symbol? alias))) (if (not (and (symbol? tag) (symbol? alias)))
@@ -452,6 +570,22 @@
(remove-alias object alias) (remove-alias object alias)
(show "You remove an alias.")))))) (show "You remove an alias."))))))


(define (do-command-destroy tag)
(if (not (symbol? tag))
(show "I didn't quite understand that.")
(database-remove tag)))

(define (do-command-aliases tag)
(if (not (symbol? tag))
(show "I didn't quite understand that.")
(let ((object (match-object tag (visible-objects 'you))))
(if (not object)
(show "You can't see that here.")
(begin
(newline)
(map (lambda (x) (display x) (display " ")) (get-aliases object))
(newline))))))

(define (do-command-message tag message-tag message) (define (do-command-message tag message-tag message)
(if (not (and (symbol? tag) (symbol? message-tag) (string? message))) (if (not (and (symbol? tag) (symbol? message-tag) (string? message)))
(show "I didn't quite understand that") (show "I didn't quite understand that")
@@ -487,10 +621,10 @@
(down . up))) (down . up)))


(define (get-cardinal-set direction) (define (get-cardinal-set direction)
(find (cut member direction <>) +cardinal-sets+))
(find (curry member direction) +cardinal-sets+))


(define (get-cardinal-aliases direction) (define (get-cardinal-aliases direction)
(perhaps (cut remove (cut eq? direction <>) <>) (get-cardinal-set direction)))
(perhaps (curry remove (curry eq? direction)) (get-cardinal-set direction)))


(define (cardinal-direction? direction) (define (cardinal-direction? direction)
(list? (member direction (flatten +cardinal-sets+)))) (list? (member direction (flatten +cardinal-sets+))))
@@ -514,7 +648,7 @@
(move-object exit-tag (get-container 'you)) (move-object exit-tag (get-container 'you))
(set-hidden exit-tag #t) (set-hidden exit-tag #t)
(set-destination exit-tag destination) (set-destination exit-tag destination)
(map (cut add-alias exit-tag <>) (get-cardinal-set direction))
(map (curry add-alias exit-tag) (get-cardinal-set direction))
(show "You create a passage.")))))))) (show "You create a passage."))))))))
(define (do-command-exit) (define (do-command-exit)
@@ -530,7 +664,7 @@
(('go x) `(enter ,x)) (('go x) `(enter ,x))
(('get x) `(take ,x)) (('get x) `(take ,x))
((x) (if (cardinal-direction? x) ((x) (if (cardinal-direction? x)
`(enter ,x)
`(enter ,x)
input)) input))
(_ input))) (_ input)))


@@ -558,6 +692,8 @@
(('unflag x y) (do-command-unflag x y)) (('unflag x y) (do-command-unflag x y))
(('alias x y) (do-command-alias x y)) (('alias x y) (do-command-alias x y))
(('unalias x y) (do-command-unalias x y)) (('unalias x y) (do-command-unalias x y))
(('destroy x) (do-command-destroy x))
(('aliases x) (do-command-aliases x))
(('message x y z) (do-command-message x y z)) (('message x y z) (do-command-message x y z))
(_ (set! success #f))) (_ (set! success #f)))
(set! success #f)))) (set! success #f))))


Laddar…
Avbryt
Spara