Merge pull request #238 from prt2121/pt/haskell-7.10.1
[jackhill/mal.git] / matlab / reader.m
CommitLineData
9a54ea18
JM
1% this is just being used as a namespace
2classdef 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
125end