diff options
| author | Joel Martin <github@martintribe.org> | 2014-11-01 15:54:48 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2015-01-09 16:15:49 -0600 |
| commit | 4d1456b98f34bfa74aea912469aa246b56273d76 (patch) | |
| tree | 8eb9751fa1d7c0f12214f298e1e2700f1c848db6 /r/reader.r | |
| parent | 0de08030ebf15d58f626d822692159f2ef1a0649 (diff) | |
| download | mal-4d1456b98f34bfa74aea912469aa246b56273d76.tar.gz mal-4d1456b98f34bfa74aea912469aa246b56273d76.zip | |
R: step0-3, readline FFI.
Diffstat (limited to 'r/reader.r')
| -rw-r--r-- | r/reader.r | 108 |
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) |
