TEST_OBJS = $(TEST_FILES:%.$(TEST_EXT)=%.o)
# Include Directories
-SRC_INCS =
+SRC_INCS = -I inc
TEST_INCS = -I inc
# Compiler and Linker Options
# Object Files
$(SRC_OBJS): %.o : %.$(SRC_EXT)
@echo $<
- @$(CSC) $(CSCFLAGS) -o $@ $<
+ @$(CSC) $(CSCFLAGS) $(SRC_INCS) -o $@ $<
$(TEST_OBJS): %.o : %.$(TEST_EXT)
@echo $<
-(declare (unit loops))
-
; For loop macro
(define-syntax for
(syntax-rules ()
(- (+ (buf-pos b) n) 1)))
(define (buf-consume! b)
+ (define current (buf-lookahead! b 1))
(buf-advance! b)
(if
(and
(begin
(buf-pos-set! b 0)
(buf-data-set! b (vector))))
- (buf-sync! b 1))
+ (buf-sync! b 1)
+ current)
--- /dev/null
+(declare (unit lex))
+
+(define-record token type text)
+
+(define token make-token)
+
+(define (match buf expect)
+ (define actual (buf-lookahead! buf 1))
+ (if (equal? expect actual)
+ (buf-consume! buf)
+ (error
+ (string-append
+ "Expected '" expect "', received '" actual "'")))
+ actual)
+
--- /dev/null
+(declare (unit lexer)
+ (uses buf))
+(include "loop.scm")
+
+(define (dlang/tokenize in)
+ (let ((ch (buf-lookahead! in 1)))
+ (cond
+ ; Whitespace
+ ((char-whitespace? ch)
+ (dlang/whitespace in)
+ (dlang/tokenize in))
+
+ ; Comment
+ ((char=? ch #\#)
+ (dlang/comment in)
+ (dlang/tokenize in))
+
+ ; Number
+ ((or
+ (and (char=? ch #\-) (char-numeric? (buf-lookahead! in 2)))
+ (char-numeric? ch))
+ (dlang/number in))
+
+ ; Character
+ ((char=? ch #\') (dlang/character in ""))
+
+ ; String
+ ((char=? ch #\") (dlang/string in ""))
+
+ ; Symbol
+ ((char=? ch #\$) (dlang/symbol in ""))
+
+ ; Parentheses
+ ((char=? ch #\()
+ (token 'lpar (string (buf-consume! in))))
+ ((char=? ch #\))
+ (token 'rpar (string (buf-consume! in))))
+
+ ; Id
+ (else
+ (dlang/id in)))))
+
+(define (dlang/whitespace in)
+ (while (char-whitespace? (buf-lookahead! in 1))
+ (buf-consume! in)))
+
+(define (dlang/comment in)
+ (match in #\#)
+ (while (not (char=? (buf-lookahead! in) #\newline))
+ (buf-consume! in)))
+
+(define (dlang/number in str) 'number)
+(define (dlang/character in str)
+ (token 'character
+ (string-append
+ (string (match in #\'))
+ (string (buf-consume! in))
+ (string (match in #\')) )))
+
+(define (dlang/string in str)
+ (token 'string
+ (string-append
+ (string (match in #\"))
+ (accumulate-till in string-append "" #\")
+ (string (match in #\")) )))
+
+(define (dlang/symbol in str)
+ (token 'symbol
+ (string-append
+ (match in #\$)
+ (token-text (dlang/id in)))))
+
+(define (dlang/id in)
+ (let loop ((acc "")
+ (ch (buf-lookahead! in 1)))
+ (if
+ (and (not (char-whitespace? ch))
+ (not (eof-object? ch)))
+ (loop (string-append acc (buf-consume! in)) (buf-lookahead! in 1)))
+ acc))
+
+
(define buffer (buf input read-char))
(buf-sync! buffer 3)
(buf-pos-set! buffer 2)
- (buf-consume! buffer)
- (and (= 0 (buf-pos buffer))
+ (and (char=? #\c (buf-consume! buffer))
+ (= 0 (buf-pos buffer))
(= 1 (vector-length (buf-data buffer)))))))
(def-test "buf-consume! should NOT clear the buffer if pos not equal to the buffer size"
(define buffer (buf input read-char))
(buf-sync! buffer 3)
(buf-pos-set! buffer 1)
- (buf-consume! buffer)
- (and (= 2 (buf-pos buffer))
+ (and (char=? #\b (buf-consume! buffer))
+ (= 2 (buf-pos buffer))
(= 3 (vector-length (buf-data buffer)))))))
(def-test "buf-consume! should NOT clear the buffer if the buffer is marked"
(buf-sync! buffer 3)
(buf-pos-set! buffer 2)
(buf-mark! buffer)
- (buf-consume! buffer)
- (and (= 3 (buf-pos buffer))
+ (and (char=? #\c (buf-consume! buffer))
+ (= 3 (buf-pos buffer))
(= 4 (vector-length (buf-data buffer)))))))