Compare commits

..

4 Commits

Author SHA1 Message Date
1d246f3489 Doesn't compile, sorry :( 2025-10-30 19:11:31 +01:00
9c2e0cc2fc Readme update 2025-10-30 15:16:18 +01:00
7f3798a9c6 Readme update 2025-10-30 15:14:53 +01:00
d850b0dadf Switched to r7rs standard 2025-10-30 15:14:02 +01:00
6 changed files with 117 additions and 108 deletions

View File

@@ -1,11 +1,8 @@
# Fudge-chez # scheme-fudge
This is the Fudge programming language implemented in Chez scheme. This is the Fudge programming language implemented in r7rs-scheme.
For the original project, go to Wannie's For the original project, go to Wannie's
[repository](https://shit-co.de/wanniepannie/fudge2.1). [repository](https://shit-co.de/wanniepannie/fudge2.1).
# Installation # Installation
To run fudge-chez, install [Chez](https://scheme.com) and run the To run fudge-chez, install a r7rs-compliant scheme implementation
program with ```chez --program fudge-chez.ss``` and execute the script fudge.ss.
## Why Chez scheme?
Because Scheme is elegant. (In theory.)

View File

@@ -1,101 +0,0 @@
(import (rnrs))
(define get-word
(lambda (file)
(let ([c (lookahead-char file)])
(cond
[(eof-object? c) ""]
[(char-alphabetic? c)
(get-char file)
(string-append (string c) (get-word file))]
[else ""]))))
(define char->digit
(lambda (c)
(- (char->integer c) (char->integer #\0))))
; get-number supports only nonnegative integers.
(define get-number
(lambda (file)
(let f ([total 0])
(let ([c (lookahead-char file)])
(if (char-numeric? c)
(begin
(get-char file)
(f (+ (* total 10) (char->digit c))))
total)))))
(define get-token
(lambda (file)
(let ([c (lookahead-char file)])
(cond
[(eof-object? c) 'end-of-file]
[(char-whitespace? c)
(get-char file)
(get-token file)]
[(char-alphabetic? c)
(get-word file)]
[(char-numeric? c)
(get-number file)]
[(eq? c #\+) (get-char file) '+]
[(eq? c #\-) (get-char file) '-]
[(eq? c #\*) (get-char file) '*]
[(eq? c #\/) (get-char file) '/]
[(eq? c #\=) (get-char file) #\=]
[else (error 'get-token "Bad character" c)]))))
(define get-tokens
(lambda (file)
(let ([token (get-token file)])
(if (eq? token 'end-of-file)
'()
(cons token (get-tokens file))))))
(define tokenize
(lambda (filename)
(let ([file (open-input-file filename)])
(get-tokens file))))
(define test-lexer-fail
(lambda (input want got)
(display "text-lexer-fail: input=")
(write input)
(display "; want: ")
(write want)
(display "; got: ")
(write got)
(display ".")
(newline)))
(define test-lexer-success
(lambda (input got)
(display "text-lexer-success: input=")
(write input)
(display "; got: ")
(write got)
(display ".")
(newline)))
(define test-lexer
(lambda (input want)
(let ([port (open-string-input-port input)])
(call/cc
(lambda (i-got-exception)
(with-exception-handler
(lambda (x)
(display "test-lexer-fail: input ")
(write input)
(display " throws ")
(write x)
(display ".")
(newline)
(i-got-exception x))
(lambda ()
(let ([got (get-tokens port)])
(if (equal? got want)
(test-lexer-success input got)
(test-lexer-fail input want got))))))))))
(test-lexer "hello world" '("hello" "world"))
(test-lexer "+ * / -" '(+ * / -))
(test-lexer "identifier = 14" '("identifier" = 14))

21
fudge.scm Normal file
View File

@@ -0,0 +1,21 @@
(import (scheme base)
(scheme write)
(scheme file)
(scheme process-context)
(lexer))
(define usage
(lambda ()
(display "usage: fudge.scm <filename>")
(newline)))
(unless (= (length (command-line)) 2)
(usage)
(exit))
(define input-string
(read-string
100000000000000
(open-input-file (car (cdr (command-line))))))
(display (tokenize input-string))

1
input.txt Normal file
View File

@@ -0,0 +1 @@
true false Struct

19
lexer-test.scm Normal file
View File

@@ -0,0 +1,19 @@
(import (scheme base)
(scheme write)
(lexer))
(define test
(lambda (input want)
(let ((got (tokenize input)))
(unless (equal? got want)
(display "test fail: input = ")
(display input)
(display "; want = ")
(display want)
(display "; got = ")
(display got)
(newline)))))
(test "Struct Enum" '(Struct Enum))
(test "this is identifier" '("this" "is" "identifier"))
(test "+ - = != :=" '(+ - = != :=))

72
lexer.sld Normal file
View File

@@ -0,0 +1,72 @@
(define-library (lexer)
(export tokenize)
(import (scheme base)
(scheme write)
(scheme char))
(begin
(define-record-type lexer
(make-lexer-with-index input index)
lexer?
(input lexer-input lexer-input-set!)
(index lexer-index lexer-index-set!))
(define-record-type lexer-error
(make-lexer-error type message)
lexer-error?
(type lexer-error-type)
(message lexer-error-message)
))
(define make-lexer
(lambda (input)
(make-lexer-with-index input 0)))
(define lexer-end?
(lambda (lexer)
(>= (lexer-index lexer)
(string-length (lexer-input lexer)))))
(define lexer-peek
(lambda (lexer)
(if (lexer-end? lexer)
(eof-object)
(string-ref (lexer-input lexer)
(lexer-index lexer)))))
(define lexer-eat!
(lambda (lexer)
(if (lexer-end? lexer)
(eof-object)
(let ((index (lexer-index lexer)))
(lexer-index-set! lexer (+ index 1))
(string-ref (lexer-input lexer) index)))))
(define get-token
(lambda (lexer)
(let ((c (lexer-peek lexer)))
(cond
((eof-object? c) "")
((char-alphabetic? c)
(lexer-eat! lexer)
(string-append (string c) (get-token lexer)))
(else "")))))
(define get-tokens
(lambda (lexer)
(let loop ((tokens #()))
(let ((c (lexer-peek lexer)))
(cond
((eof-object? c) tokens)
((char-whitespace? c)
(lexer-eat! lexer)
(loop tokens))
((char-alphabetic? c)
(let ((token (get-token lexer)))
(if (lexer-error? token)
token
(loop )))))))
(define tokenize
(lambda (input)
(get-tokens (make-lexer input))))))