1 module orelang.Parser;
2 import orelang.expression.ImmediateValue,
3        orelang.expression.SymbolValue,
4        orelang.Value;
5 import std.regex,
6        std.conv;
7 
8 auto nrgx = ctRegex!"[0-9]";
9 
10 class Parser {
11   static size_t nextBracket(string code) {
12     size_t index,
13            leftCount = 1,
14            rightCount;
15 
16     while (leftCount != rightCount) {
17       if (code[index] == '(') { leftCount++; }
18       if (code[index] == ')') { rightCount++; }
19       ++index;
20     }
21 
22     return index;
23   }
24 
25   static Value[] parse(string code) {
26     Value[] _out;
27 
28     for (size_t i; i < code.length; ++i) {
29       char ch = code[i];
30 
31       if (ch == ' ') {
32         continue;
33       } else {
34         if (ch == '(') {
35           size_t j = nextBracket(code[i+1..$]);
36 
37           _out ~= new Value(parse(code[i+1..i+j]));
38 
39           i += j;
40         } else if (ch == ')') {
41           return _out;
42         } else {
43           if (ch.to!string.match(nrgx) || (i + 1 < code.length && ch == '-' && code[i + 1].to!string.match(nrgx))) {
44             string tmp;
45             size_t j = i;
46 
47             do {
48               tmp ~= code[j];
49               ++j;
50             } while (
51                 j < code.length &&
52                 ((code[j] != ' ' && code[j].to!string.match(nrgx))
53                  ||  (code[j] == '.' && j + 1 < code.length && code[j + 1].to!string.match(nrgx)))
54                 );
55 
56             _out ~= new Value(tmp.to!double);
57 
58             i = j - 1;
59           } else if (ch == '\"' || ch == '\'') {
60             if (ch == '\'' && i + 1 < code.length && code[i + 1] == '(') {
61               size_t j = nextBracket(code[i + 2..$]) + 1;
62 
63               _out ~= new Value(new ImmediateValue(new Value(parse(code[i+2..j+i]))));
64 
65               i += j;
66             } else {
67               string tmp;
68               size_t j = i + 1;
69 
70               while (j < code.length && code[j] != ch) {
71                 if (j < code.length) {
72                   tmp ~= code[j];
73                 } else {
74                   throw new Error("Syntax Error");
75                 }
76 
77                 ++j;
78               }
79 
80               _out ~= new Value(tmp);
81               i = j;
82             }
83           } else {
84             string tmp;
85             size_t j = i;
86 
87             while (
88                 j < code.length && code[j] != '\"' && code[j] != '\'' &&
89                 code[j] != '(' && code[j] != ')' && code[j] != ' '
90                 ) {
91               tmp ~= code[j];
92               ++j;
93             }
94 
95             if (tmp == "true") {
96               _out ~= new Value(true);
97             } else if (tmp == "false") {
98               _out ~= new Value(false);
99             } else if (tmp == "null") {
100               _out ~= new Value;
101             } else {
102               _out ~= new Value(new SymbolValue(tmp));
103             }
104 
105             i = j;
106           }
107         }
108       }
109     }
110 
111     return _out;
112   }
113 }