source: branches/xpascal/Parser.pas

Last change on this file was 236, checked in by chronos, 17 months ago
  • Fixed: Var function parameters processed correctly for both user defined and internal functions.
File size: 7.2 KB
Line 
1unit Parser;
2
3interface
4
5uses
6 Classes, SysUtils, Tokenizer, Source;
7
8type
9
10 { TParser }
11
12 TParser = class
13 private
14 FOnError: TErrorEvent;
15 procedure TokenizerError(Pos: TPoint; Text: string);
16 procedure InitSystemBlock(Block: TBlock);
17 protected
18 Tokenizer: TTokenizer;
19 function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; virtual;
20 public
21 Source: string;
22 Prog: TProgram;
23 procedure Parse;
24 procedure Error(Text: string);
25 constructor Create;
26 destructor Destroy; override;
27 property OnError: TErrorEvent read FOnError write FOnError;
28 end;
29
30
31implementation
32
33resourcestring
34 SCannotParseProgram = 'Cannot parse program.';
35
36{ TParser }
37
38procedure TParser.TokenizerError(Pos: TPoint; Text: string);
39begin
40 if Assigned(FOnError) then
41 FOnError(Pos, Text);
42end;
43
44procedure TParser.InitSystemBlock(Block: TBlock);
45var
46 I: Integer;
47 TypeBoolean: TType;
48 TypeString: TType;
49 TypeInteger: TType;
50begin
51 TypeBoolean := Block.Types.AddNew('Boolean');
52 with TypeBoolean do begin
53 ValueClass := TValueBoolean;
54 with Functions.AddNew('_Assign') do begin
55 Params.AddNew('Source', TypeBoolean);
56 ResultType := TypeBoolean;
57 end;
58 with Functions.AddNew('_Equal') do begin
59 Params.AddNew('A', TypeBoolean);
60 Params.AddNew('B', TypeBoolean);
61 ResultType := TypeBoolean;
62 end;
63 with Functions.AddNew('_NotEqual') do begin
64 Params.AddNew('A', TypeBoolean);
65 Params.AddNew('B', TypeBoolean);
66 ResultType := TypeBoolean;
67 end;
68 with Functions.AddNew('_Not') do begin
69 Params.AddNew('A', TypeBoolean);
70 ResultType := TypeBoolean;
71 end;
72 end;
73 TypeString := Block.Types.AddNew('string');
74 with TypeString do begin
75 ValueClass := TValueString;
76 with Functions.AddNew('_Assign') do begin
77 Params.AddNew('Source', TypeString);
78 ResultType := TypeString;
79 end;
80 with Functions.AddNew('_Add') do begin
81 Params.AddNew('A', TypeString);
82 Params.AddNew('B', TypeString);
83 ResultType := TypeString;
84 end;
85 with Functions.AddNew('_Equal') do begin
86 Params.AddNew('A', TypeString);
87 Params.AddNew('B', TypeString);
88 ResultType := TypeBoolean;
89 end;
90 with Functions.AddNew('_NotEqual') do begin
91 Params.AddNew('A', TypeString);
92 Params.AddNew('B', TypeString);
93 ResultType := TypeBoolean;
94 end;
95 end;
96 TypeInteger := Block.Types.AddNew('Integer');
97 with TypeInteger do begin
98 ValueClass := TValueInteger;
99 with Functions.AddNew('_Assign') do begin
100 Params.AddNew('Source', TypeInteger);
101 ResultType := TypeInteger;
102 end;
103 with Functions.AddNew('_Add') do begin
104 Params.AddNew('A', TypeInteger);
105 Params.AddNew('B', TypeInteger);
106 ResultType := TypeInteger;
107 end;
108 with Functions.AddNew('_Sub') do begin
109 Params.AddNew('A', TypeInteger);
110 Params.AddNew('B', TypeInteger);
111 ResultType := TypeInteger;
112 end;
113 with Functions.AddNew('_Mul') do begin
114 Params.AddNew('A', TypeInteger);
115 Params.AddNew('B', TypeInteger);
116 ResultType := TypeInteger;
117 end;
118 with Functions.AddNew('_IntDiv') do begin
119 Params.AddNew('A', TypeInteger);
120 Params.AddNew('B', TypeInteger);
121 ResultType := TypeInteger;
122 end;
123 with Functions.AddNew('_Mod') do begin
124 Params.AddNew('A', TypeInteger);
125 Params.AddNew('B', TypeInteger);
126 ResultType := TypeInteger;
127 end;
128 with Functions.AddNew('_Equal') do begin
129 Params.AddNew('A', TypeInteger);
130 Params.AddNew('B', TypeInteger);
131 ResultType := TypeBoolean;
132 end;
133 with Functions.AddNew('_NotEqual') do begin
134 Params.AddNew('A', TypeInteger);
135 Params.AddNew('B', TypeInteger);
136 ResultType := TypeBoolean;
137 end;
138 with Functions.AddNew('_Lesser') do begin
139 Params.AddNew('A', TypeInteger);
140 Params.AddNew('B', TypeInteger);
141 ResultType := TypeBoolean;
142 end;
143 with Functions.AddNew('_Higher') do begin
144 Params.AddNew('A', TypeInteger);
145 Params.AddNew('B', TypeInteger);
146 ResultType := TypeBoolean;
147 end;
148 with Functions.AddNew('_LesserOrEqual') do begin
149 Params.AddNew('A', TypeInteger);
150 Params.AddNew('B', TypeInteger);
151 ResultType := TypeBoolean;
152 end;
153 with Functions.AddNew('_HigherOrEqual') do begin
154 Params.AddNew('A', TypeInteger);
155 Params.AddNew('B', TypeInteger);
156 ResultType := TypeBoolean;
157 end;
158 with Functions.AddNew('_Shr') do begin
159 Params.AddNew('A', TypeInteger);
160 Params.AddNew('B', TypeInteger);
161 ResultType := TypeInteger;
162 end;
163 with Functions.AddNew('_Shl') do begin
164 Params.AddNew('A', TypeInteger);
165 Params.AddNew('B', TypeInteger);
166 ResultType := TypeInteger;
167 end;
168 with Functions.AddNew('_And') do begin
169 Params.AddNew('A', TypeInteger);
170 Params.AddNew('B', TypeInteger);
171 ResultType := TypeInteger;
172 end;
173 with Functions.AddNew('_Or') do begin
174 Params.AddNew('A', TypeInteger);
175 Params.AddNew('B', TypeInteger);
176 ResultType := TypeInteger;
177 end;
178 with Functions.AddNew('_Xor') do begin
179 Params.AddNew('A', TypeInteger);
180 Params.AddNew('B', TypeInteger);
181 ResultType := TypeInteger;
182 end;
183 end;
184 with Block.Functions.AddNew('IntToStr') do begin
185 InternalName := 'IntToStr';
186 Params.AddNew('Value', TypeInteger);
187 ResultType := TypeString;
188 end;
189 with Block.Functions.AddNew('StrToInt') do begin
190 InternalName := 'StrToInt';
191 Params.AddNew('Value', TypeString);
192 ResultType := TypeInteger;
193 end;
194 with Block.Functions.AddNew('BoolToStr') do begin
195 InternalName := 'BoolToStr';
196 Params.AddNew('Value', TypeBoolean);
197 ResultType := TypeString;
198 end;
199 with Block.Functions.AddNew('StrToBool') do begin
200 InternalName := 'StrToBool';
201 Params.AddNew('Value', TypeString);
202 ResultType := TypeBoolean;
203 end;
204 with Block.Procedures.AddNew('WriteLn') do begin
205 InternalName := 'WriteLn';
206 Params.AddNew('Text', TypeString);
207 end;
208 with Block.Procedures.AddNew('Write') do begin
209 InternalName := 'Write';
210 Params.AddNew('Text', TypeString);
211 end;
212 with Block.Procedures.AddNew('ReadLn') do begin
213 InternalName := 'ReadLn';
214 with Params.AddNew('Text', TypeString) do
215 Kind := pkVar;
216 end;
217 with Block.Procedures.AddNew('Read') do begin
218 InternalName := 'Read';
219 with Params.AddNew('Text', TypeString) do
220 Kind := pkVar;
221 end;
222
223 for I := 0 to Block.Functions.Count - 1 do
224 Block.Functions[I].InitVariables;
225 for I := 0 to Block.Procedures.Count - 1 do
226 Block.Procedures[I].InitVariables;
227end;
228
229function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;
230begin
231 Result := False;
232end;
233
234procedure TParser.Parse;
235var
236 NewProg: TProgram;
237 SystemBlock: TBlock;
238begin
239 Tokenizer.Source := Source;
240 Tokenizer.Init;
241 SystemBlock := TBlock.Create;
242 InitSystemBlock(SystemBlock);
243 if ParseProgram(SystemBlock, NewProg) then begin
244 Prog := NewProg;
245 end else Tokenizer.Error(SCannotParseProgram);
246end;
247
248procedure TParser.Error(Text: string);
249begin
250 if Assigned(FOnError) then
251 FOnError(Tokenizer.Pos.Pos, Text);
252end;
253
254constructor TParser.Create;
255begin
256 Tokenizer := TTokenizer.Create;
257 Tokenizer.OnError := TokenizerError;
258end;
259
260destructor TParser.Destroy;
261begin
262 FreeAndNil(Tokenizer);
263 inherited;
264end;
265
266end.
267
Note: See TracBrowser for help on using the repository browser.