Commit | Line | Data |
---|---|---|
4d1456b9 JM |
1 | ..reader.. <- TRUE |
2 | ||
3 | if(!exists("..types..")) source("types.r") | |
4 | ||
5 | new.Reader <- function(tokens) { | |
6 | e <- structure(new.env(), class="Reader") | |
7 | e$tokens <- tokens | |
8 | e$position <- 1 | |
9 | e | |
10 | } | |
11 | ||
12 | Reader.peek <- function(rdr) { | |
13 | if (rdr$position > length(rdr$tokens)) return(NULL) | |
14 | rdr$tokens[[rdr$position]] | |
15 | } | |
16 | ||
17 | Reader.next <- function(rdr) { | |
18 | if (rdr$position > length(rdr$tokens)) return(NULL) | |
19 | rdr$position <- rdr$position + 1 | |
20 | rdr$tokens[[rdr$position-1]] | |
21 | } | |
22 | ||
23 | tokenize <- function(str) { | |
24 | re <- "[\\s,]*(~@|[\\[\\]\\{\\}\\(\\)'`~^@]|\"(?:\\\\.|[^\\\\\"])*\"|;.*|[^\\s\\[\\]\\{\\}\\('\"`,;\\)]*)" | |
25 | m <- lapply(regmatches(str, gregexpr(re, str, perl=TRUE)), | |
26 | function(e) sub("^[\\s,]+", "", e, perl=TRUE)) | |
27 | res <- list() | |
28 | i <- 1 | |
29 | for(v in m[[1]]) { | |
30 | if (v == "") next | |
31 | res[[i]] <- v | |
32 | i <- i+1 | |
33 | } | |
34 | res | |
35 | } | |
36 | ||
37 | re_match <- function(re, str) { length(grep(re, c(str))) > 0 } | |
38 | ||
39 | read_atom <- function(rdr) { | |
40 | token <- Reader.next(rdr) | |
41 | if (re_match("^-?[0-9][0-9.]*$", token)) { | |
42 | as.numeric(token) | |
43 | } else if (substr(token,1,1) == "\"") { | |
01feedfe JM |
44 | gsub("\\\\n", "\\n", |
45 | gsub("\\\\\"", "\"", | |
46 | substr(token, 2, nchar(token)-1))) | |
4d1456b9 | 47 | } else if (token == "nil") { |
01feedfe | 48 | nil |
4d1456b9 JM |
49 | } else if (token == "true") { |
50 | TRUE | |
51 | } else if (token == "false") { | |
52 | FALSE | |
53 | } else { | |
54 | as.symbol(token) | |
55 | } | |
56 | } | |
57 | ||
58 | read_seq <- function(rdr, start="(", end=")") { | |
59 | lst <- list() | |
60 | token <- Reader.next(rdr) | |
61 | if (token != start) { | |
62 | throw(concat("expected '", start, "'")) | |
63 | } | |
64 | repeat { | |
65 | token <- Reader.peek(rdr) | |
66 | if (is.null(token)) { | |
67 | throw(concat("expected '", end, "', got EOF")) | |
68 | } | |
69 | if (token == end) break | |
70 | lst[[length(lst)+1]] <- read_form(rdr) | |
71 | } | |
72 | Reader.next(rdr) | |
73 | new.listl(lst) | |
74 | } | |
75 | ||
76 | read_form <- function(rdr) { | |
77 | token <- Reader.peek(rdr) | |
78 | if (token == ")") { | |
79 | throw("unexpected ')'") | |
80 | } else if (token == "(") { | |
81 | new.listl(read_seq(rdr)) | |
82 | } else if (token == "]") { | |
83 | throw("unexpected ']'") | |
84 | } else if (token == "[") { | |
85 | new.vectorl(read_seq(rdr, "[", "]")) | |
86 | } else { | |
87 | read_atom(rdr) | |
88 | } | |
89 | } | |
90 | ||
91 | read_str <- function(str) { | |
92 | tokens <- tokenize(str) | |
01feedfe | 93 | if (length(tokens) == 0) return(nil) |
4d1456b9 JM |
94 | return(read_form(new.Reader(tokens))) |
95 | } | |
96 | ||
97 | #cat("---\n") | |
98 | #print(tokenize("123")) | |
99 | #cat("---\n") | |
100 | #print(tokenize(" ( 123 456 abc \"def\" ) ")) | |
101 | ||
102 | #rdr <- new.reader(tokenize(" ( 123 456 abc \"def\" ) ")) | |
103 | #Reader.peek(rdr) | |
104 | #Reader.next(rdr) | |
105 | #Reader.next(rdr) | |
106 | #Reader.next(rdr) | |
107 | #Reader.next(rdr) | |
108 | #Reader.next(rdr) | |
109 | #Reader.next(rdr) | |
110 | #Reader.next(rdr) |