source: branches/interpreter/interpreter4/Source.pas

Last change on this file was 108, checked in by chronos, 7 years ago

*Modified: Better parsing of variable reference.

File size: 9.7 KB
Line 
1unit Source;
2
3{$mode delphi}
4
5interface
6
7type
8 PBeginEnd = ^TBeginEnd;
9 PAssignment = ^TAssignment;
10 PVariable = ^TVariable;
11 PVariableRef = ^TVariableRef;
12 PConstant = ^TConstant;
13 PIfThenElse = ^TIfThenElse;
14 PWhileDo = ^TWhileDo;
15 PExpression = ^TExpression;
16 PExecution = ^TExecution;
17 PType = ^TType;
18 PTypes = ^TTypes;
19 PEnumerationStates = ^TEnumerationStates;
20 PFunction = ^TFunction;
21 PVariables = ^TVariables;
22 PGetValue = ^TGetValue;
23
24 TOperator = (opNone, opAdd, opSubtract, opAnd, opOr, opNot, opEqual, opNotEqual,
25 opLess, opGreater, opLessOrEqual, opGreaterOrEqual);
26
27 TBaseType = (btNone, btBoolean, btInteger, btChar, btShortString, btArray,
28 btSimple, btPointer, btRecord, btSimpleForward, btEnumeration, btFunction,
29 btRecordCase);
30
31 TType = record
32 TypeList: PTypes;
33 Name: string;
34 BaseType: TBaseType;
35 case TBaseType of
36 btPointer: (PointedType: PType);
37 btRecord: (Fields: PTypes);
38 btSimple: (Simple: PType);
39 btSimpleForward: (ForwardType: shortstring);
40 btEnumeration: (States: PEnumerationStates);
41 btArray: (ArrayItemType: PType);
42 btFunction: (Func: PFunction);
43 btRecordCase: (CaseItems: PTypes);
44 end;
45
46 TEnumerationStates = record
47 Items: array of string;
48 end;
49
50 { TTypes }
51
52 TTypes = record
53 ParentList: PTypes;
54 Items: array of TType;
55 procedure Add(DataType: TType);
56 function GetByName(Name: string): PType;
57 function GetLast: PType;
58 end;
59
60 TConstant = record
61 Name: shortstring;
62 DataType: PType;
63 Index: Integer;
64 case TBaseType of
65 btChar: (ValueChar: Char);
66 btInteger: (ValueInteger: Integer);
67 btShortString: (ValueString: ShortString);
68 btBoolean: (ValueBoolean: Boolean);
69 btRecord: (ValueRecord: PVariables);
70 btArray: (ValueArray: PVariables);
71 end;
72
73 { TConstants }
74
75 TConstants = record
76 Items: array of TConstant;
77 procedure Add(Constant: TConstant);
78 function GetByName(Name: string): PConstant;
79 end;
80 PConstants = ^TConstants;
81
82 TVariable = record
83 Name: string;
84 DataType: PType;
85 Index: Integer;
86 Value: TConstant;
87 end;
88
89 { TVariables }
90
91 TVariables = record
92 ParentList: PVariables;
93 Items: array of TVariable;
94 procedure Add(Variable: TVariable);
95 function GetByName(Name: string): PVariable;
96 function GetLast: PVariable;
97 end;
98
99 TVariableRef = record
100 Variable: PVariable;
101 case TBaseType of
102 btRecord: (Field: PType);
103 btArray: (Index: PGetValue);
104 end;
105
106 TFunctionParameter = record
107 Name: string;
108 DataType: PType;
109 Output: Boolean;
110 end;
111
112 { TFunctionParameters }
113
114 TFunctionParameters = record
115 TypeList: PTypes;
116 Items: array of TFunctionParameter;
117 procedure Add(Param: TFunctionParameter);
118 end;
119 PFunctionParameters = ^TFunctionParameters;
120
121 TFunctionCall = procedure ;
122
123 TCmdType = (ctNone, ctWhileDo, ctIfThenElse, ctBeginEnd, ctAssignment, ctExecution);
124 TCommand = record
125 CmdType: TCmdType;
126 case Integer of
127 0: (WhileDo: PWhileDo);
128 1: (IfThenElse: PIfThenElse);
129 2: (BeginEnd: PBeginEnd);
130 3: (Assignment: PAssignment);
131 4: (Execution: PExecution);
132 end;
133 PCommand = ^TCommand;
134
135 { TBeginEnd }
136
137 TBeginEnd = record
138 Commands: array of TCommand;
139 procedure Add;
140 function GetLast: PCommand;
141 end;
142
143 TReadType = (rtVariable, rtConstant, rtExpression, rtFunctionCall, rtValue);
144 TGetValue = record
145 ReadType: TReadType;
146 case TReadType of
147 rtVariable: (VariableRef: PVariableRef);
148 rtConstant: (Constant: PConstant);
149 rtExpression: (Expression: PExpression);
150 rtFunctionCall: (FunctionCall: PExecution);
151 rtValue: (Value: TConstant);
152 end;
153
154 TExpNodeType = (ntNone, ntValue, ntOperator);
155
156 TExpression = record
157 NodeType: TExpNodeType;
158 OperatorType: TOperator;
159 Items: array of TExpression;
160 Value: TGetValue;
161 Parentheses: Boolean;
162 Associated: Boolean;
163 end;
164
165 TAssignment = record
166 Destination: PVariableRef;
167 Source: TGetValue;
168 end;
169
170 TIfThenElse = record
171 Condition: TGetValue;
172 DoThen: TCommand;
173 DoElse: TCommand;
174 end;
175
176 TWhileDo = record
177 Condition: TGetValue;
178 Command: TCommand;
179 end;
180
181 { TFunction }
182
183 TFunction = record // TCommand
184 Name: string;
185 Parameters: TFunctionParameters;
186 ReturnType: PType;
187 BeginEnd: TBeginEnd;
188 Variables: TVariables;
189 Types: TTypes;
190 ParentRecord: PType;
191 end;
192
193 { TFunctions }
194
195 TFunctions = record
196 Items: array of TFunction;
197 procedure Add(Func: TFunction);
198 function GetByName(Name: string): PFunction;
199 function GetLast: PFunction;
200 end;
201
202 TExecutionParams = record
203 Items: array of TGetValue;
204 end;
205
206 TExecution = record
207 Func: PFunction;
208 Parameters: TExecutionParams;
209 end;
210
211 TDirective = record
212 Name: string;
213 Value: string;
214 end;
215 PDirective = ^TDirective;
216
217 TUses = record
218 Items: array of string;
219 end;
220 PUses = ^TUses;
221
222 TUnit = record
223 Name: string;
224 Types: TTypes;
225 Variables: TVariables;
226 Constants: TConstants;
227 UsesSection: TUses;
228 Functions: TFunctions;
229 end;
230 PUnit = ^TUnit;
231
232 { TUnits }
233
234 TUnits = record
235 Items: array of TUnit;
236 function GetByName(Name: string): PUnit;
237 end;
238
239 TProgramCode = record
240 Name: string;
241 BaseDir: string;
242 Variables: TVariables;
243 Constants: TConstants;
244 Types: TTypes;
245 Functions: TFunctions;
246 BeginEnd: TBeginEnd;
247 UsesSection: TUses;
248 Units: TUnits;
249 end;
250 PProgramCode = ^TProgramCode;
251
252function ConstantCreate(Name: string; DataType: PType): TConstant;
253function VariableCreate(Name: string; DataType: PType): TVariable;
254function FunctionCreate(Name: string; DataType: PType): TFunction;
255function TypeCreate(Name: string; BaseType: TBaseType): TType;
256function FunctionParameterCreate(Name: string; DataType: PType; Output: Boolean = False): TFunctionParameter;
257
258var
259 OperatorString: array[TOperator] of string = ('', '+', '-', 'and', 'or', 'not',
260 '=', '<>', '<', '>', '<=', '>=');
261
262const
263 OperatorPrecedence: array[0..10] of TOperator = (opNot, opAnd, opOr, opAdd,
264 opSubtract, opEqual, opNotEqual, opLess, opGreater, opLessOrEqual, opGreaterOrEqual);
265 Keywords: array[0..18] of string = ('begin', 'end', 'if', 'then', 'else', 'while',
266 'do', 'type', 'var', 'const', 'uses', 'unit', 'program', 'array', 'procedure',
267 'function', 'interface', 'implementation', 'record');
268
269
270implementation
271
272function ConstantCreate(Name: string; DataType: PType): TConstant;
273begin
274 Result.Name := Name;
275 Result.DataType := DataType;
276end;
277
278function VariableCreate(Name: string; DataType: PType): TVariable;
279begin
280 Result.Name := Name;
281 Result.DataType := DataType;
282end;
283
284function FunctionCreate(Name: string; DataType: PType): TFunction;
285begin
286 Result.Name := Name;
287 Result.ReturnType := DataType;
288end;
289
290function TypeCreate(Name: string; BaseType:TBaseType): TType;
291begin
292 Result.Name := Name;
293 Result.BaseType := BaseType;
294end;
295
296function FunctionParameterCreate(Name: string; DataType: PType; Output: Boolean = False): TFunctionParameter;
297begin
298 Result.Name := Name;
299 Result.DataType := DataType;
300 Result.Output := Output;
301end;
302
303{ TUnits }
304
305function TUnits.GetByName(Name: string): PUnit;
306var
307 I: Integer;
308begin
309 I := 0;
310 while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
311 if I < Length(Items) then Result := @Items[I]
312 else Result := nil;
313end;
314
315{ TBeginEnd }
316
317procedure TBeginEnd.Add;
318begin
319 SetLength(Commands, Length(Commands) + 1);
320end;
321
322function TBeginEnd.GetLast: PCommand;
323begin
324 Result := @Commands[Length(Commands) - 1];
325end;
326
327{ TConstants }
328
329procedure TConstants.Add(Constant: TConstant);
330begin
331 SetLength(Items, Length(Items) + 1);
332 Items[Length(Items) - 1] := Constant;
333 Items[Length(Items) - 1].Index := Length(Items) - 1;
334end;
335
336function TConstants.GetByName(Name: string): PConstant;
337var
338 I: Integer;
339begin
340 I := 0;
341 while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
342 if I < Length(Items) then Result := @Items[I]
343 else Result := nil;
344end;
345
346{ TVariables }
347
348procedure TVariables.Add(Variable: TVariable);
349begin
350 SetLength(Items, Length(Items) + 1);
351 Items[Length(Items) - 1] := Variable;
352 Items[Length(Items) - 1].Index := Length(Items) - 1;
353end;
354
355function TVariables.GetByName(Name: string): PVariable;
356var
357 I: Integer;
358begin
359 I := 0;
360 while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
361 if I < Length(Items) then Result := @Items[I]
362 else begin
363 if ParentList <> nil then Result := ParentList^.GetByName(Name)
364 else Result := nil;
365 end;
366end;
367
368function TVariables.GetLast: PVariable;
369begin
370 Result := @Items[Length(Items) - 1];
371end;
372
373{ TFunctionParameters }
374
375procedure TFunctionParameters.Add(Param: TFunctionParameter);
376begin
377 SetLength(Items, Length(Items) + 1);
378 Items[Length(Items) - 1] := Param;
379end;
380
381{ TTypes }
382
383procedure TTypes.Add(DataType: TType);
384begin
385 SetLength(Items, Length(Items) + 1);
386 Items[Length(Items) - 1] := DataType;
387end;
388
389function TTypes.GetByName(Name: string): PType;
390var
391 I: Integer;
392begin
393 I := 0;
394 while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
395 if I < Length(Items) then Result := @Items[I]
396 else begin
397 if ParentList <> nil then Result := ParentList^.GetByName(Name)
398 else Result := nil;
399 end;
400end;
401
402function TTypes.GetLast: PType;
403begin
404 Result := @Items[Length(Items) - 1];
405end;
406
407{ TFunctions }
408
409procedure TFunctions.Add(Func: TFunction);
410begin
411 SetLength(Items, Length(Items) + 1);
412 Items[Length(Items) - 1] := Func;
413end;
414
415function TFunctions.GetByName(Name: string): PFunction;
416var
417 I: Integer;
418begin
419 I := 0;
420 while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
421 if I < Length(Items) then Result := @Items[I]
422 else Result := nil;
423end;
424
425function TFunctions.GetLast: PFunction;
426begin
427 Result := @Items[Length(Items) - 1];
428end;
429
430end.
431
Note: See TracBrowser for help on using the repository browser.