2 ;████████╗██╗ ██╗██╗ ██╗███╗ ██╗
3 ;╚══██╔══╝██║ ██║██║ ██║████╗ ██║
4 ; ██║ ███████║██║ ██║██╔██╗ ██║
5 ; ██║ ██╔══██║██║ ██║██║╚██╗██║
6 ; ██║ ██║ ██║╚██████╔╝██║ ╚████║
7 ; ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
9 ;Copyright © 2023 Simon Forman
11 ;This file is part of Thun
13 ;Thun is free software: you can redistribute it and/or modify
14 ;it under the terms of the GNU General Public License as published by
15 ;the Free Software Foundation, either version 3 of the License, or
16 ;(at your option) any later version.
18 ;Thun is distributed in the hope that it will be useful,
19 ;but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;GNU General Public License for more details.
23 ;You should have received a copy of the GNU General Public License
24 ;along with Thun. If not see <http://www.gnu.org/licenses/>.
28 (import (chicken string))
31 ;(load "defs.scm") ; csc -prologue defs.scm joy.scm
33 (chicken-script (load "defs.scm"))
36 (define (joy stack expression dict)
37 (if (null? expression)
39 (if (string? (car expression))
41 (joy-eval (car expression) stack (cdr expression) dict)
43 (joy (cons (car expression) stack) (cdr expression) dict))))
45 (define (joy-eval symbol stack expression dict)
46 (define (is-it? name) (string=? symbol name))
48 ((is-it? "+") (values (joy-add stack) expression dict))
49 ((is-it? "-") (values (joy-sub stack) expression dict))
50 ((is-it? "*") (values (joy-mul stack) expression dict))
51 ((is-it? "mul") (values (joy-mul stack) expression dict))
52 ((is-it? "dup") (values (cons (car stack) stack) expression dict))
53 ((is-it? "stack") (values (cons stack stack) expression dict))
54 ((is-it? "swaack") (values (cons (cdr stack) (car stack)) expression dict))
55 ((hash-table-exists? dict symbol)
56 (values stack (append (hash-table-ref dict symbol) expression) dict))
57 (else (error "Unknown word."))))
59 (define (joy-add stack) (cons (+ (cadr stack) (car stack)) (cddr stack)))
60 (define (joy-sub stack) (cons (- (cadr stack) (car stack)) (cddr stack)))
61 (define (joy-mul stack) (cons (* (cadr stack) (car stack)) (cddr stack)))
65 (define (string-replace str from to)
66 (string-intersperse (string-split str from #t) to))
68 (define (tokenize str)
70 (string-replace (string-replace str "]" " ] ") "[" " [ ")))
72 (define (tokenator token)
73 (cond ((string->number token) (string->number token))
74 ((string=? token "true") #t)
75 ((string=? token "false") #f)
78 (define (expect-right-bracket tokens acc)
80 (error "Missing closing bracket.")
81 (expect-right-bracket-lookahead (car tokens) (cdr tokens) acc)))
83 (define (expect-right-bracket-lookahead token tokens acc)
84 (cond ((string=? token "]") (values acc tokens))
86 (receive (sub_list rest) (expect-right-bracket tokens '())
87 (receive (el rrest) (expect-right-bracket rest acc)
88 (values (cons sub_list el) rrest))))
90 (receive (el rest) (expect-right-bracket tokens acc)
91 (values (cons (tokenator token) el) rest)))))
93 (define (one-token-lookahead token tokens)
94 (cond ((string=? token "]") (error "Extra closing bracket."))
95 ((string=? token "[") (expect-right-bracket tokens '()))
96 (else (values (tokenator token) tokens))))
98 (define (parse0 tokens acc)
101 (receive (term rest_of_tokens)
102 (one-token-lookahead (car tokens) (cdr tokens))
103 (cons term (parse0 rest_of_tokens acc)))))
105 (define (parse tokens) (parse0 tokens '()))
107 (define (text->expression text) (parse (tokenize text)))
110 (define (joy-term->string term)
111 (cond ((boolean? term) (if term "true" "false"))
112 ((number? term) (->string term))
113 ((list? term) (conc "[" (joy-expression->string term) "]"))
116 (define (joy-expression->string expr)
117 (string-intersperse (map joy-term->string expr) " "))
120 (receive (stack _dict)
121 (joy '() (text->expression text) (initialize))
122 (joy-expression->string stack)))
126 (load-defs (make-hash-table string=? string-hash)))
128 (define (load-defs dict)
129 (map (lambda (def) (add-def def dict)) (defs)) ;defs is defined in defs.scm
132 (define (add-def def dict)
133 (let ((def_list (text->expression def)))
134 (hash-table-set! dict (car def_list) (cdr def_list))))
137 (display (doit "1 2 3 [4 5 6] swaack stack"))