Commit | Line | Data |
---|---|---|
9a54ea18 JM |
1 | % this is just being used as a namespace |
2 | classdef reader | |
3 | methods (Static = true) | |
4 | function tokens = tokenize(str) | |
7f567f36 | 5 | re = '[\s,]*(~@|[\[\]{}()''`~^@]|"(?:\\.|[^\\"])*"|;[^\n]*|[^\s\[\]{}(''"`,;)]*)'; |
9a54ea18 JM |
6 | % extract the capture group (to ignore spaces and commas) |
7 | tokens = cellfun(@(x) x(1), regexp(str, re, 'tokens')); | |
7f567f36 JM |
8 | comments = cellfun(@(x) length(x) > 0 && x(1) == ';', tokens); |
9 | tokens = tokens(~comments); | |
9a54ea18 JM |
10 | end |
11 | ||
12 | function atm = read_atom(rdr) | |
13 | token = rdr.next(); | |
14 | %fprintf('in read_atom: %s\n', token); | |
15 | if not(isempty(regexp(token, '^-?[0-9]+$', 'match'))) | |
16 | atm = str2double(token); | |
17 | elseif strcmp(token(1), '"') | |
18 | atm = token(2:length(token)-1); | |
6d12affa JM |
19 | atm = strrep(atm, '\"', '"'); |
20 | atm = strrep(atm, '\n', char(10)); | |
6a572dff | 21 | elseif strcmp(token(1), ':') |
e0188ffe | 22 | atm = types.keyword(token(2:end)); |
d6624158 JM |
23 | elseif strcmp(token, 'nil') |
24 | atm = types.nil; | |
9a54ea18 JM |
25 | elseif strcmp(token, 'true') |
26 | atm = true; | |
27 | elseif strcmp(token, 'false') | |
28 | atm = false; | |
29 | else | |
30 | atm = types.Symbol(token); | |
31 | end | |
32 | end | |
33 | ||
6a572dff JM |
34 | function seq = read_seq(rdr, start, last) |
35 | %fprintf('in read_seq\n'); | |
36 | seq = {}; | |
9a54ea18 | 37 | token = rdr.next(); |
6a572dff | 38 | if not(strcmp(token, start)) |
0b234e13 | 39 | error(sprintf('expected ''%s''', start)); |
9a54ea18 JM |
40 | end |
41 | token = rdr.peek(); | |
42 | while true | |
43 | if eq(token, false) | |
0b234e13 | 44 | error(sprintf('expected ''%s''', last)); |
9a54ea18 | 45 | end |
6a572dff JM |
46 | if strcmp(token, last), break, end |
47 | seq{end+1} = reader.read_form(rdr); | |
9a54ea18 JM |
48 | token = rdr.peek(); |
49 | end | |
50 | rdr.next(); | |
51 | end | |
52 | ||
6a572dff JM |
53 | function lst = read_list(rdr) |
54 | seq = reader.read_seq(rdr, '(', ')'); | |
55 | lst = types.List(seq{:}); | |
56 | end | |
57 | ||
58 | function vec = read_vector(rdr) | |
59 | seq = reader.read_seq(rdr, '[', ']'); | |
60 | vec = types.Vector(seq{:}); | |
61 | end | |
62 | ||
63 | function map = read_hash_map(rdr) | |
64 | seq = reader.read_seq(rdr, '{', '}'); | |
65 | map = types.HashMap(seq{:}); | |
66 | end | |
67 | ||
9a54ea18 JM |
68 | function ast = read_form(rdr) |
69 | %fprintf('in read_form\n'); | |
70 | token = rdr.peek(); | |
c3023f26 JM |
71 | switch token |
72 | case '''' | |
73 | rdr.next(); | |
6a572dff JM |
74 | ast = types.List(types.Symbol('quote'), ... |
75 | reader.read_form(rdr)); | |
c3023f26 JM |
76 | case '`' |
77 | rdr.next(); | |
6a572dff JM |
78 | ast = types.List(types.Symbol('quasiquote'), ... |
79 | reader.read_form(rdr)); | |
c3023f26 JM |
80 | case '~' |
81 | rdr.next(); | |
6a572dff JM |
82 | ast = types.List(types.Symbol('unquote'), ... |
83 | reader.read_form(rdr)); | |
c3023f26 JM |
84 | case '~@' |
85 | rdr.next(); | |
6a572dff JM |
86 | ast = types.List(types.Symbol('splice-unquote'), ... |
87 | reader.read_form(rdr)); | |
53942f88 JM |
88 | case '^' |
89 | rdr.next(); | |
90 | meta = reader.read_form(rdr); | |
91 | ast = types.List(types.Symbol('with-meta'), ... | |
92 | reader.read_form(rdr), meta); | |
93 | case '@' | |
94 | rdr.next(); | |
95 | ast = types.List(types.Symbol('deref'), ... | |
96 | reader.read_form(rdr)); | |
97 | ||
9a54ea18 JM |
98 | case ')' |
99 | error('unexpected '')'''); | |
100 | case '(' | |
101 | ast = reader.read_list(rdr); | |
6a572dff JM |
102 | case ']' |
103 | error('unexpected '']'''); | |
104 | case '[' | |
105 | ast = reader.read_vector(rdr); | |
106 | case '}' | |
107 | error('unexpected ''}'''); | |
108 | case '{' | |
109 | ast = reader.read_hash_map(rdr); | |
9a54ea18 JM |
110 | otherwise |
111 | ast = reader.read_atom(rdr); | |
112 | end | |
113 | end | |
114 | ||
115 | function ast = read_str(str) | |
116 | %fprintf('in read_str\n'); | |
117 | tokens = reader.tokenize(str); | |
751ab516 | 118 | rdr = types.Reader(tokens); |
9a54ea18 JM |
119 | ast = reader.read_form(rdr); |
120 | end | |
121 | end | |
122 | end |