--- /dev/null
+#-------------------
+# Main Configuration
+#-------------------
+DIST_DIR = dist/
+
+#---------------------
+# Include Sub-Projects
+#---------------------
+SUB_PROJS = sclpl sclpl-rdr
+CLEAN_PROJS = $(addprefix clean-,$(SUB_PROJS))
+
+#----------------
+# Top-Level Tasks
+#----------------
+.PHONY: $(SUB_PROJS) $(CLEAN_PROJS)
+
+all: $(DIST_DIR) $(SUB_PROJS)
+
+$(SUB_PROJS):
+ @$(MAKE) -C src/$@ release
+
+$(DIST_DIR):
+ @mkdir -p $(DIST_DIR)
+
+$(CLEAN_PROJS):
+ @$(MAKE) -C src/$(subst clean-,,$@) clean
+
+clean: $(CLEAN_PROJS)
+ @rm -rf $(DIST_DIR)
+
--- /dev/null
+###############################################################################
+#
+# Name: SCLPL Compiler Driver
+# Author: Mike Lowis
+# License: BSD 2-Clause
+# Description: The main driver application that compiles SCLPL source code to
+# native binaries using a suite of command line tools.
+#
+###############################################################################
+
+# Utility Function Definitions
+#-----------------------------
+# Function for generating a file list
+flist = $(shell env find $(1) -name "*.$(strip $(2))" -print)
+
+# Project and Artifact Names
+#---------------------------
+BIN_NAME = sclpl-rdr
+TEST_RUNNER = $(BIN_NAME)-test
+
+# File and Directory Settings
+#----------------------------
+# Root Directories
+PROJ_ROOT = ../../
+DIST_ROOT = $(PROJ_ROOT)/dist
+SRC_ROOT = src/
+TEST_ROOT = test/
+
+# File Extensions
+SRC_EXT = scm
+TEST_EXT = scm
+
+# Source File Lists
+SRC_FILES = $(call flist, $(SRC_ROOT), $(SRC_EXT))
+TEST_FILES = $(call flist, $(TEST_ROOT), $(TEST_EXT))
+
+# Object File Lists
+SRC_OBJS = $(SRC_FILES:%.$(SRC_EXT)=%.o)
+TEST_OBJS = $(TEST_FILES:%.$(TEST_EXT)=%.o)
+
+# Include Directories
+SRC_INCS = -I inc
+TEST_INCS = -I inc
+
+# Compiler and Linker Options
+#----------------------------
+CSC = csc
+CSCFLAGS = -c -explicit-use
+
+# Build Rules
+#------------
+
+# List all rules not named for files/folders on disk
+.PHONY: all release
+
+all: release
+
+#release: test $(BIN_NAME)
+release: $(DIST_ROOT) $(BIN_NAME)
+ @echo Copying to $(DIST_ROOT)...
+ @cp $(BIN_NAME)* $(DIST_ROOT)
+
+#test: $(TEST_RUNNER)
+# @echo Running unit tests...
+# @./$(TEST_RUNNER)
+
+# Binaries
+$(BIN_NAME): $(SRC_OBJS)
+ @echo Linking $@...
+ @$(CSC) -o $@ $(SRC_OBJS) $(LIBS)
+
+$(TEST_RUNNER): $(SRC_OBJS) $(TEST_OBJS)
+ @echo Linking $@...
+ @$(CSC) -o $@ $(TEST_OBJS) $(filter-out src/main.o,$(SRC_OBJS))
+
+# Object Files
+$(SRC_OBJS): %.o : %.$(SRC_EXT)
+ @echo $<
+ @$(CSC) $(CSCFLAGS) $(SRC_INCS) -o $@ $<
+
+#$(TEST_OBJS): %.o : %.$(TEST_EXT)
+# @echo $<
+# @$(CSC) $(CSCFLAGS) $(TEST_INCS) -o $@ $<
+
+$(DIST_ROOT):
+ mkdir $(DIST_ROOT)
+
+# Cleanup
+clean:
+ @echo Cleaning up...
+ @$(RM) $(TEST_OBJS)
+ @$(RM) $(SRC_OBJS)
+ @$(RM) $(BIN_NAME)*
+# @$(RM) $(TEST_RUNNER)*
+
--- /dev/null
+(declare (uses sclpl-rdr))
+
+(interpret (current-input-port))
+
--- /dev/null
+(declare (unit sclpl-rdr) (uses library))
+
+; Top-Level Interpret Function
+;------------------------------------------------------------------------------
+(define (interpret port)
+ (define parsed-expr (expr port))
+ (print parsed-expr)
+ (if (not (null? parsed-expr))
+ (interpret port)))
+
+(define core-forms '("def" "set!" "if" "begin" "func"))
+
+(define syntaxes '())
+
+; Expression Parsing Functions
+;------------------------------------------------------------------------------
+(define (expr port)
+ (define tok (read-token port))
+ (cond [(eof-object? tok) '()]
+ [(core-form? tok) (read-form-from-till port (string-append "sclpl/" tok) "end")]
+ [(syntax? tok) (read-form-from-till port tok "end")]
+ [(equal? tok "{") (cons 'sclpl/infix (read-form-till port "}"))]
+ [(equal? tok "(") (cons 'sclpl/list (read-form-till port ")"))]
+ [(equal? tok "[") (cons 'sclpl/prefix (read-form-till port "]"))]
+ [else (atom-or-fn-app port tok)]))
+
+(define (core-form? tok)
+ (member tok core-forms))
+
+(define (syntax? tok)
+ (member tok syntaxes))
+
+(define (read-form-from-till port stok etok)
+ (cons stok (read-form-till port etok)))
+
+(define (read-form-till port etok)
+ (define currexpr (expr port))
+ (cond [(eof-object? currexpr) (error "Unterminated expression")]
+ [(and (string? currexpr)
+ (equal? currexpr etok)) '()]
+ [else (cons currexpr (read-form-till port etok))]))
+
+(define (atom-or-fn-app port tok)
+ (consume-ws-to-nl port)
+ (if (char=? (peek-char port) #\()
+ (cons 'sclpl/apply (cons tok (cdr (expr port))))
+ tok))
+
+(define (consume-ws-to-nl port)
+ (if (and (char-whitespace? (peek-char port))
+ (not (char=? (peek-char port) #\newline)))
+ (begin (read-char port)
+ (consume-ws-to-nl port))))
+
+; Tokenizer Functions
+;------------------------------------------------------------------------------
+(define (read-token port)
+ (define next (peek-char port))
+ (cond [(eof-object? next) (read-char port)]
+ [(char-whitespace? next) (consume-whitespace port)]
+ [(char=? next #\#) (consume-comment port)]
+ [(punctuation? next) (punctuation port)]
+ [else (read-atom port "")]))
+
+(define (consume-whitespace port)
+ (if (char-whitespace? (peek-char port))
+ (begin (read-char port)
+ (read-token port))
+ (read-token port)))
+
+(define (consume-comment port)
+ (if (not (char=? #\newline (peek-char port)))
+ (begin (read-char port) (consume-comment port))
+ (begin (read-char port) (read-token port))))
+
+(define (punctuation? ch)
+ (and (not (eof-object? ch))
+ (case ch ((#\( #\) #\{ #\}
+ #\[ #\] #\, #\;) #t)
+ (else #f))))
+
+(define (punctuation port)
+ (string (read-char port)))
+
+(define (read-atom port str)
+ (if (atom-char? (peek-char port))
+ (read-atom port (string-append str (string (read-char port))))
+ str))
+
+(define (atom-char? ch)
+ (and (not (eof-object? ch))
+ (not (char-whitespace? ch))
+ (not (punctuation? ch))))
+
--- /dev/null
+###############################################################################
+#
+# Name: SCLPL Compiler Driver
+# Author: Mike Lowis
+# License: BSD 2-Clause
+# Description: The main driver application that compiles SCLPL source code to
+# native binaries using a suite of command line tools.
+#
+###############################################################################
+
+# Utility Function Definitions
+#-----------------------------
+# Function for generating a file list
+flist = $(shell env find $(1) -name "*.$(strip $(2))" -print)
+
+# Project and Artifact Names
+#---------------------------
+BIN_NAME = sclpl
+TEST_RUNNER = sclpl-test
+
+# File and Directory Settings
+#----------------------------
+# Root Directories
+PROJ_ROOT = ../../
+DIST_ROOT = $(PROJ_ROOT)/dist
+SRC_ROOT = src/
+TEST_ROOT = test/
+
+# File Extensions
+SRC_EXT = scm
+TEST_EXT = scm
+
+# Source File Lists
+SRC_FILES = $(call flist, $(SRC_ROOT), $(SRC_EXT))
+TEST_FILES = $(call flist, $(TEST_ROOT), $(TEST_EXT))
+
+# Object File Lists
+SRC_OBJS = $(SRC_FILES:%.$(SRC_EXT)=%.o)
+TEST_OBJS = $(TEST_FILES:%.$(TEST_EXT)=%.o)
+
+# Include Directories
+SRC_INCS = -I inc
+TEST_INCS = -I inc
+
+# Compiler and Linker Options
+#----------------------------
+CSC = csc
+CSCFLAGS = -c -explicit-use
+
+# Build Rules
+#------------
+
+# List all rules not named for files/folders on disk
+.PHONY: all release
+
+all: release
+
+#release: test $(BIN_NAME)
+release: $(DIST_ROOT) $(BIN_NAME)
+ @echo Copying to $(DIST_ROOT)...
+ @cp $(BIN_NAME)* $(DIST_ROOT)
+
+#test: $(TEST_RUNNER)
+# @echo Running unit tests...
+# @./$(TEST_RUNNER)
+
+# Binaries
+$(BIN_NAME): $(SRC_OBJS)
+ @echo Linking $@...
+ @$(CSC) -o $@ $(SRC_OBJS) $(LIBS)
+
+$(TEST_RUNNER): $(SRC_OBJS) $(TEST_OBJS)
+ @echo Linking $@...
+ @$(CSC) -o $@ $(TEST_OBJS) $(filter-out src/main.o,$(SRC_OBJS))
+
+# Object Files
+$(SRC_OBJS): %.o : %.$(SRC_EXT)
+ @echo $<
+ @$(CSC) $(CSCFLAGS) $(SRC_INCS) -o $@ $<
+
+#$(TEST_OBJS): %.o : %.$(TEST_EXT)
+# @echo $<
+# @$(CSC) $(CSCFLAGS) $(TEST_INCS) -o $@ $<
+
+$(DIST_ROOT):
+ mkdir $(DIST_ROOT)
+
+# Cleanup
+clean:
+ @echo Cleaning up...
+ @$(RM) $(TEST_OBJS)
+ @$(RM) $(SRC_OBJS)
+ @$(RM) $(BIN_NAME)*
+# @$(RM) $(TEST_RUNNER)*
+
--- /dev/null
+(declare (uses sclpl))
+
+(interpret (current-input-port))
+
--- /dev/null
+(declare (unit sclpl) (uses library))
+
+(define (interpret port)
+ (define expression (read port))
+ (print (eval expression))
+ (if (not (null? expression))
+ (interpret port)))
+