77dae072b343446807524ad4a8d3af906dcd2277
[jackhill/mal.git] / matlab / reader.m
1 % this is just being used as a namespace
2 classdef reader
3 methods (Static = true)
4 function tokens = tokenize(str)
5 re = '[\s,]*(~@|[\[\]{}()''`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}(''"`,;)]*)';
6 % extract the capture group (to ignore spaces and commas)
7 tokens = cellfun(@(x) x(1), regexp(str, re, 'tokens'));
8 end
9
10 function atm = read_atom(rdr)
11 token = rdr.next();
12 %fprintf('in read_atom: %s\n', token);
13 if not(isempty(regexp(token, '^-?[0-9]+$', 'match')))
14 atm = str2double(token);
15 elseif strcmp(token(1), '"')
16 atm = token(2:length(token)-1);
17 elseif strcmp(token, 'nil')
18 atm = types.nil;
19 elseif strcmp(token, 'true')
20 atm = true;
21 elseif strcmp(token, 'false')
22 atm = false;
23 else
24 atm = types.Symbol(token);
25 end
26 end
27
28 function lst = read_list(rdr)
29 %fprintf('in read_list\n');
30 lst = {};
31 token = rdr.next();
32 if not(strcmp(token, '('))
33 error('expected ''(''');
34 end
35 token = rdr.peek();
36 while true
37 if eq(token, false)
38 error('expected '')''');
39 end
40 if strcmp(token, ')'), break, end
41 lst{length(lst)+1} = reader.read_form(rdr);
42 token = rdr.peek();
43 end
44 rdr.next();
45 end
46
47 function ast = read_form(rdr)
48 %fprintf('in read_form\n');
49 token = rdr.peek();
50 switch token(1)
51 case ')'
52 error('unexpected '')''');
53 case '('
54 ast = reader.read_list(rdr);
55 otherwise
56 ast = reader.read_atom(rdr);
57 end
58 end
59
60 function ast = read_str(str)
61 %fprintf('in read_str\n');
62 tokens = reader.tokenize(str);
63 rdr = Reader(tokens);
64 ast = reader.read_form(rdr);
65 end
66 end
67 end