aboutsummaryrefslogtreecommitdiff
path: root/r/reader.r
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-11-01 15:54:48 -0500
committerJoel Martin <github@martintribe.org>2015-01-09 16:15:49 -0600
commit4d1456b98f34bfa74aea912469aa246b56273d76 (patch)
tree8eb9751fa1d7c0f12214f298e1e2700f1c848db6 /r/reader.r
parent0de08030ebf15d58f626d822692159f2ef1a0649 (diff)
downloadmal-4d1456b98f34bfa74aea912469aa246b56273d76.tar.gz
mal-4d1456b98f34bfa74aea912469aa246b56273d76.zip
R: step0-3, readline FFI.
Diffstat (limited to 'r/reader.r')
-rw-r--r--r/reader.r108
1 files changed, 108 insertions, 0 deletions
diff --git a/r/reader.r b/r/reader.r
new file mode 100644
index 0000000..d2ab486
--- /dev/null
+++ b/r/reader.r
@@ -0,0 +1,108 @@
+..reader.. <- TRUE
+
+if(!exists("..types..")) source("types.r")
+
+new.Reader <- function(tokens) {
+ e <- structure(new.env(), class="Reader")
+ e$tokens <- tokens
+ e$position <- 1
+ e
+}
+
+Reader.peek <- function(rdr) {
+ if (rdr$position > length(rdr$tokens)) return(NULL)
+ rdr$tokens[[rdr$position]]
+}
+
+Reader.next <- function(rdr) {
+ if (rdr$position > length(rdr$tokens)) return(NULL)
+ rdr$position <- rdr$position + 1
+ rdr$tokens[[rdr$position-1]]
+}
+
+tokenize <- function(str) {
+ re <- "[\\s,]*(~@|[\\[\\]\\{\\}\\(\\)'`~^@]|\"(?:\\\\.|[^\\\\\"])*\"|;.*|[^\\s\\[\\]\\{\\}\\('\"`,;\\)]*)"
+ m <- lapply(regmatches(str, gregexpr(re, str, perl=TRUE)),
+ function(e) sub("^[\\s,]+", "", e, perl=TRUE))
+ res <- list()
+ i <- 1
+ for(v in m[[1]]) {
+ if (v == "") next
+ res[[i]] <- v
+ i <- i+1
+ }
+ res
+}
+
+re_match <- function(re, str) { length(grep(re, c(str))) > 0 }
+
+read_atom <- function(rdr) {
+ token <- Reader.next(rdr)
+ if (re_match("^-?[0-9][0-9.]*$", token)) {
+ as.numeric(token)
+ } else if (substr(token,1,1) == "\"") {
+ substr(token, 2, nchar(token)-1)
+ } else if (token == "nil") {
+ NULL
+ } else if (token == "true") {
+ TRUE
+ } else if (token == "false") {
+ FALSE
+ } else {
+ as.symbol(token)
+ }
+}
+
+read_seq <- function(rdr, start="(", end=")") {
+ lst <- list()
+ token <- Reader.next(rdr)
+ if (token != start) {
+ throw(concat("expected '", start, "'"))
+ }
+ repeat {
+ token <- Reader.peek(rdr)
+ if (is.null(token)) {
+ throw(concat("expected '", end, "', got EOF"))
+ }
+ if (token == end) break
+ lst[[length(lst)+1]] <- read_form(rdr)
+ }
+ Reader.next(rdr)
+ new.listl(lst)
+}
+
+read_form <- function(rdr) {
+ token <- Reader.peek(rdr)
+ if (token == ")") {
+ throw("unexpected ')'")
+ } else if (token == "(") {
+ new.listl(read_seq(rdr))
+ } else if (token == "]") {
+ throw("unexpected ']'")
+ } else if (token == "[") {
+ new.vectorl(read_seq(rdr, "[", "]"))
+ } else {
+ read_atom(rdr)
+ }
+}
+
+read_str <- function(str) {
+ tokens <- tokenize(str)
+ if (length(tokens) == 0) return(NULL)
+ return(read_form(new.Reader(tokens)))
+}
+
+#cat("---\n")
+#print(tokenize("123"))
+#cat("---\n")
+#print(tokenize(" ( 123 456 abc \"def\" ) "))
+
+#rdr <- new.reader(tokenize(" ( 123 456 abc \"def\" ) "))
+#Reader.peek(rdr)
+#Reader.next(rdr)
+#Reader.next(rdr)
+#Reader.next(rdr)
+#Reader.next(rdr)
+#Reader.next(rdr)
+#Reader.next(rdr)
+#Reader.next(rdr)