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)); | |
47699629 | 21 | atm = strrep(atm, '\\', '\'); |
6a572dff | 22 | elseif strcmp(token(1), ':') |
47699629 JM |
23 | s = token(2:end); |
24 | atm = type_utils.keyword(s); | |
d6624158 | 25 | elseif strcmp(token, 'nil') |
47699629 | 26 | atm = type_utils.nil; |
9a54ea18 JM |
27 | elseif strcmp(token, 'true') |
28 | atm = true; | |
29 | elseif strcmp(token, 'false') | |
30 | atm = false; | |
31 | else | |
32 | atm = types.Symbol(token); | |
33 | end | |
34 | end | |
35 | ||
6a572dff JM |
36 | function seq = read_seq(rdr, start, last) |
37 | %fprintf('in read_seq\n'); | |
38 | seq = {}; | |
9a54ea18 | 39 | token = rdr.next(); |
6a572dff | 40 | if not(strcmp(token, start)) |
0b234e13 | 41 | error(sprintf('expected ''%s''', start)); |
9a54ea18 JM |
42 | end |
43 | token = rdr.peek(); | |
44 | while true | |
45 | if eq(token, false) | |
0b234e13 | 46 | error(sprintf('expected ''%s''', last)); |
9a54ea18 | 47 | end |
6a572dff JM |
48 | if strcmp(token, last), break, end |
49 | seq{end+1} = reader.read_form(rdr); | |
9a54ea18 JM |
50 | token = rdr.peek(); |
51 | end | |
52 | rdr.next(); | |
53 | end | |
54 | ||
6a572dff JM |
55 | function lst = read_list(rdr) |
56 | seq = reader.read_seq(rdr, '(', ')'); | |
57 | lst = types.List(seq{:}); | |
58 | end | |
59 | ||
60 | function vec = read_vector(rdr) | |
61 | seq = reader.read_seq(rdr, '[', ']'); | |
62 | vec = types.Vector(seq{:}); | |
63 | end | |
64 | ||
65 | function map = read_hash_map(rdr) | |
66 | seq = reader.read_seq(rdr, '{', '}'); | |
67 | map = types.HashMap(seq{:}); | |
68 | end | |
69 | ||
9a54ea18 JM |
70 | function ast = read_form(rdr) |
71 | %fprintf('in read_form\n'); | |
72 | token = rdr.peek(); | |
c3023f26 JM |
73 | switch token |
74 | case '''' | |
75 | rdr.next(); | |
6a572dff JM |
76 | ast = types.List(types.Symbol('quote'), ... |
77 | reader.read_form(rdr)); | |
c3023f26 JM |
78 | case '`' |
79 | rdr.next(); | |
6a572dff JM |
80 | ast = types.List(types.Symbol('quasiquote'), ... |
81 | reader.read_form(rdr)); | |
c3023f26 JM |
82 | case '~' |
83 | rdr.next(); | |
6a572dff JM |
84 | ast = types.List(types.Symbol('unquote'), ... |
85 | reader.read_form(rdr)); | |
c3023f26 JM |
86 | case '~@' |
87 | rdr.next(); | |
6a572dff JM |
88 | ast = types.List(types.Symbol('splice-unquote'), ... |
89 | reader.read_form(rdr)); | |
53942f88 JM |
90 | case '^' |
91 | rdr.next(); | |
92 | meta = reader.read_form(rdr); | |
93 | ast = types.List(types.Symbol('with-meta'), ... | |
94 | reader.read_form(rdr), meta); | |
95 | case '@' | |
96 | rdr.next(); | |
97 | ast = types.List(types.Symbol('deref'), ... | |
98 | reader.read_form(rdr)); | |
99 | ||
9a54ea18 JM |
100 | case ')' |
101 | error('unexpected '')'''); | |
102 | case '(' | |
103 | ast = reader.read_list(rdr); | |
6a572dff JM |
104 | case ']' |
105 | error('unexpected '']'''); | |
106 | case '[' | |
107 | ast = reader.read_vector(rdr); | |
108 | case '}' | |
109 | error('unexpected ''}'''); | |
110 | case '{' | |
111 | ast = reader.read_hash_map(rdr); | |
9a54ea18 JM |
112 | otherwise |
113 | ast = reader.read_atom(rdr); | |
114 | end | |
115 | end | |
116 | ||
117 | function ast = read_str(str) | |
118 | %fprintf('in read_str\n'); | |
119 | tokens = reader.tokenize(str); | |
47699629 | 120 | %disp(tokens); |
751ab516 | 121 | rdr = types.Reader(tokens); |
9a54ea18 JM |
122 | ast = reader.read_form(rdr); |
123 | end | |
124 | end | |
125 | end |