b2d12d1b9f2890f22949e4a0a6daf1fb1508bb8f
[sdk] / compiler / libec2 / src / lexing.ec
1 public import "ecere"
2 public import "ec"
3
4 public enum TokenType2 : TokenType
5 {
6    dummy;
7
8    property char { }
9
10    property bool isSpecifier
11    {
12       get
13       {
14          return isQualifier || this == _char || this == _short || this == _int || this == _uint || this == _int64 || this == _long || this == _signed ||
15                 this == _unsigned || this == _float || this == _double || this == _void ||
16                 this == _valist || this == thisClass || this == typedObject || this == anyObject ||
17                 this == _typedef || this == _struct || this == _class || this == _union || this == _enum ||
18                 this == _typeof || this == subClass;
19       }
20    }
21
22    property bool isQualifier
23    {
24       get
25       {
26          return this == _extern || this == _static || this == _auto || this == _register || this == _const || this == _volatile;
27       }
28    }
29
30    property bool isUnaryOperator
31    {
32       get
33       {
34          return this == '&' || this == '*' || this == '+' || this == '-' || this == '~' || this == '!' || this == _delete || this == _incref;
35       }
36    }
37
38    property bool isAssignmentOperator
39    {
40       get
41       {
42           return this == '='|| this == mulAssign || this == divAssign || this == modAssign ||
43                this == addAssign || this == subAssign || this == leftAssign || this == rightAssign ||
44                this == andAssign || this == xorAssign || this == orAssign;
45       }
46    }
47
48    void print()
49    {
50       if(this < 256)
51          Print((char)this);
52       else
53       {
54          switch(this)
55          {
56             case _void: Print("void"); break;
57             case _char: Print("char"); break;
58             case _short: Print("short"); break;
59             case _int: Print("int"); break;
60             case _long: Print("long"); break;
61             case _int64: Print("int64"); break;
62             case _unsigned: Print("unsigned"); break;
63             case _signed: Print("signed"); break;
64             case _float: Print("float"); break;
65             case _double: Print("double"); break;
66             case _typedef: Print("typedef"); break;
67             case _extern: Print("extern"); break;
68             case _static: Print("static"); break;
69             case _auto: Print("auto"); break;
70             case _register: Print("register"); break;
71             case _uint: Print("uint"); break;
72             case _const: Print("const"); break;
73             case _volatile: Print("volatile"); break;
74             case _valist: Print("va_list"); break;
75             case thisClass: Print("thisclass"); break;
76             case typedObject: Print("typed_Object"); break;
77             case anyObject: Print("any_object"); break;
78             case _struct: Print("struct"); break;
79             case _union: Print("union"); break;
80             case _enum: Print("enum"); break;
81             case _class: Print("class"); break;
82
83             case _typeof: Print("typeof"); break;
84             case subClass: Print("subclass"); break;
85
86             case incOp: Print("++"); break;
87             case decOp: Print("--"); break;
88             case sizeOf: Print("sizeof "); break;
89             case leftOp: Print("<<"); break;
90             case rightOp: Print(">>"); break;
91             case leOp: Print("<="); break;
92             case geOp: Print(">="); break;
93             case eqOp: Print("=="); break;
94             case neOp: Print("!="); break;
95             case andOp: Print("&&"); break;
96             case orOp: Print("||"); break;
97            case mulAssign: Print("*="); break;
98            case divAssign: Print("/="); break;
99            case modAssign: Print("%="); break;
100            case addAssign: Print("+="); break;
101            case subAssign: Print("-="); break;
102            case leftAssign: Print("<<="); break;
103            case rightAssign: Print(">>="); break;
104            case andAssign: Print("&="); break;
105            case xorAssign: Print("^="); break;
106            case orAssign: Print("|="); break;
107          }
108       }
109    }
110 };
111
112 class Token
113 {
114    TokenType2 type;
115    String text;
116    ~Token()
117    {
118       delete text;
119    }
120 }
121
122 Token token, nextToken;
123
124 int ambiguous, stackPos;
125 Array<Token> tokenStack { minAllocSize = 256 };
126
127 Token readToken()
128 {
129    if(!nextToken) peekToken();
130    delete token;
131    token = nextToken;
132    nextToken = null;
133    return token;
134 }
135
136 Token peekToken()
137 {
138    if(!nextToken)
139    {
140       if(stackPos < tokenStack.count)
141       {
142          nextToken = tokenStack[stackPos++];
143          incref nextToken;
144          if(!ambiguous && stackPos == tokenStack.count)
145          {
146             tokenStack.Free();
147             stackPos = 0;
148          }
149       }
150       else
151       {
152          TokenType2 type = (TokenType2)LexEc();
153          if(type)
154          {
155             nextToken = { _refCount = 1, type = type, text = CopyString(GetYYText()) };
156             if(ambiguous)
157             {
158                stackPos++;
159                tokenStack.Add(nextToken);
160                incref nextToken;
161             }
162          }
163       }
164    }
165    return nextToken;
166 }
167
168 int pushAmbiguity()
169 {
170    if(!ambiguous && nextToken && stackPos == tokenStack.count)
171    {
172       stackPos++;
173       tokenStack.Add(nextToken);
174       incref nextToken;
175    }
176    ambiguous++;
177    return stackPos - (nextToken ? 1 : 0);
178 }
179
180 void clearAmbiguity()
181 {
182    if(!--ambiguous && stackPos > 0)
183    {
184       int i;
185       for(i = 0; i < stackPos; i++)
186          delete tokenStack[i];
187       if(tokenStack.size > stackPos)
188          memmove(tokenStack.array, tokenStack.array + stackPos, (tokenStack.size - stackPos) * sizeof(Token));
189       tokenStack.size -= stackPos;
190       stackPos = 0;
191    }
192 }
193
194 void popAmbiguity(int i)
195 {
196    delete token;
197    delete nextToken;
198
199    stackPos = i;
200    clearAmbiguity();
201    token = null;
202    nextToken = null;
203 }
204
205 public void lexAll()
206 {
207    while(readToken())
208    {
209       if(token.type < 256)
210          PrintLn((char)token.type);
211       else
212          PrintLn(token.type, " (", token.text, ")");
213    }
214 }
215
216 public void initParser(File f)
217 {
218    SetFileInput(f);
219    delete token;
220    delete nextToken;
221    tokenStack.size = 0;
222    stackPos = 0;
223    ambiguous = 0;
224 }