| 1 | unit Source;
|
|---|
| 2 |
|
|---|
| 3 | {$mode delphi}
|
|---|
| 4 |
|
|---|
| 5 | interface
|
|---|
| 6 |
|
|---|
| 7 | type
|
|---|
| 8 | PBeginEnd = ^TBeginEnd;
|
|---|
| 9 | PAssignment = ^TAssignment;
|
|---|
| 10 | PVariable = ^TVariable;
|
|---|
| 11 | PConstant = ^TConstant;
|
|---|
| 12 | PIfThenElse = ^TIfThenElse;
|
|---|
| 13 | PWhileDo = ^TWhileDo;
|
|---|
| 14 | PExpression = ^TExpression;
|
|---|
| 15 | PExecution = ^TExecution;
|
|---|
| 16 |
|
|---|
| 17 | TOperator = (opNone, opAdd, opSubtract, opAnd, opOr, opNot, opEqual, opNotEqual);
|
|---|
| 18 |
|
|---|
| 19 | TBaseType = (btNone, btBoolean, btInteger, btChar, btShortString, btArray);
|
|---|
| 20 |
|
|---|
| 21 | TType = record
|
|---|
| 22 | Name: string;
|
|---|
| 23 | BaseType: TBaseType;
|
|---|
| 24 | end;
|
|---|
| 25 | PType = ^TType;
|
|---|
| 26 |
|
|---|
| 27 | { TTypes }
|
|---|
| 28 |
|
|---|
| 29 | TTypes = record
|
|---|
| 30 | Items: array of TType;
|
|---|
| 31 | procedure Add(DataType: TType);
|
|---|
| 32 | function GetByName(Name: string): PType;
|
|---|
| 33 | function GetLast: PType;
|
|---|
| 34 | end;
|
|---|
| 35 |
|
|---|
| 36 | TVariable = record
|
|---|
| 37 | Name: string;
|
|---|
| 38 | DataType: PType;
|
|---|
| 39 | Index: Integer;
|
|---|
| 40 | end;
|
|---|
| 41 |
|
|---|
| 42 | { TVariables }
|
|---|
| 43 |
|
|---|
| 44 | TVariables = record
|
|---|
| 45 | Items: array of TVariable;
|
|---|
| 46 | procedure Add(Variable: TVariable);
|
|---|
| 47 | function GetByName(Name: string): PVariable;
|
|---|
| 48 | end;
|
|---|
| 49 | PVariables = ^TVariables;
|
|---|
| 50 |
|
|---|
| 51 | TConstant = record
|
|---|
| 52 | Name: shortstring;
|
|---|
| 53 | DataType: PType;
|
|---|
| 54 | Index: Integer;
|
|---|
| 55 | case TBaseType of
|
|---|
| 56 | btChar: (ValueChar: Char);
|
|---|
| 57 | btInteger: (ValueInteger: Integer);
|
|---|
| 58 | btShortString: (ValueString: shortstring);
|
|---|
| 59 | btBoolean: (ValueBoolean: Boolean);
|
|---|
| 60 | end;
|
|---|
| 61 |
|
|---|
| 62 | { TConstants }
|
|---|
| 63 |
|
|---|
| 64 | TConstants = record
|
|---|
| 65 | Items: array of TConstant;
|
|---|
| 66 | procedure Add(Constant: TConstant);
|
|---|
| 67 | function GetByName(Name: string): PConstant;
|
|---|
| 68 | end;
|
|---|
| 69 | PConstants = ^TConstants;
|
|---|
| 70 |
|
|---|
| 71 | TFunctionParameter = record
|
|---|
| 72 | Name: string;
|
|---|
| 73 | DataType: PType;
|
|---|
| 74 | Output: Boolean;
|
|---|
| 75 | end;
|
|---|
| 76 |
|
|---|
| 77 | { TFunctionParameters }
|
|---|
| 78 |
|
|---|
| 79 | TFunctionParameters = record
|
|---|
| 80 | Items: array of TFunctionParameter;
|
|---|
| 81 | procedure Add(Param: TFunctionParameter);
|
|---|
| 82 | end;
|
|---|
| 83 | PFunctionParameters = ^TFunctionParameters;
|
|---|
| 84 |
|
|---|
| 85 | TFunctionCall = procedure ;
|
|---|
| 86 |
|
|---|
| 87 | TCmdType = (ctNone, ctWhileDo, ctIfThenElse, ctBeginEnd, ctAssignment, ctExecution);
|
|---|
| 88 | TCommand = record
|
|---|
| 89 | CmdType: TCmdType;
|
|---|
| 90 | case Integer of
|
|---|
| 91 | 0: (WhileDo: PWhileDo);
|
|---|
| 92 | 1: (IfThenElse: PIfThenElse);
|
|---|
| 93 | 2: (BeginEnd: PBeginEnd);
|
|---|
| 94 | 3: (Assignment: PAssignment);
|
|---|
| 95 | 4: (Execution: PExecution);
|
|---|
| 96 | end;
|
|---|
| 97 | PCommand = ^TCommand;
|
|---|
| 98 |
|
|---|
| 99 | { TBeginEnd }
|
|---|
| 100 |
|
|---|
| 101 | TBeginEnd = record
|
|---|
| 102 | Commands: array of TCommand;
|
|---|
| 103 | procedure Add;
|
|---|
| 104 | function GetLast: PCommand;
|
|---|
| 105 | end;
|
|---|
| 106 |
|
|---|
| 107 | TReadType = (rtVariable, rtConstant, rtExpression, rtFunctionCall, rtValue);
|
|---|
| 108 | TGetValue = record
|
|---|
| 109 | ReadType: TReadType;
|
|---|
| 110 | case TReadType of
|
|---|
| 111 | rtVariable: (Variable: PVariable);
|
|---|
| 112 | rtConstant: (Constant: PConstant);
|
|---|
| 113 | rtExpression: (Expression: PExpression);
|
|---|
| 114 | rtFunctionCall: (FunctionCall: PExecution);
|
|---|
| 115 | rtValue: (Value: TConstant);
|
|---|
| 116 | end;
|
|---|
| 117 | PGetValue = ^TGetValue;
|
|---|
| 118 |
|
|---|
| 119 | TExpNodeType = (ntNone, ntValue, ntOperator);
|
|---|
| 120 |
|
|---|
| 121 | TExpression = record
|
|---|
| 122 | NodeType: TExpNodeType;
|
|---|
| 123 | OperatorType: TOperator;
|
|---|
| 124 | Items: array of TExpression;
|
|---|
| 125 | Value: TGetValue;
|
|---|
| 126 | Parentheses: Boolean;
|
|---|
| 127 | Associated: Boolean;
|
|---|
| 128 | end;
|
|---|
| 129 |
|
|---|
| 130 | TAssignment = record
|
|---|
| 131 | Destination: PVariable;
|
|---|
| 132 | Source: TGetValue;
|
|---|
| 133 | end;
|
|---|
| 134 |
|
|---|
| 135 | TIfThenElse = record
|
|---|
| 136 | Condition: TGetValue;
|
|---|
| 137 | DoThen: TCommand;
|
|---|
| 138 | DoElse: TCommand;
|
|---|
| 139 | end;
|
|---|
| 140 |
|
|---|
| 141 | TWhileDo = record
|
|---|
| 142 | Condition: TGetValue;
|
|---|
| 143 | Command: TCommand;
|
|---|
| 144 | end;
|
|---|
| 145 |
|
|---|
| 146 | { TFunction }
|
|---|
| 147 |
|
|---|
| 148 | TFunction = record // TCommand
|
|---|
| 149 | Name: string;
|
|---|
| 150 | Parameters: TFunctionParameters;
|
|---|
| 151 | ReturnType: PType;
|
|---|
| 152 | BeginEnd: TBeginEnd;
|
|---|
| 153 | Variables: TVariables;
|
|---|
| 154 | end;
|
|---|
| 155 | PFunction = ^TFunction;
|
|---|
| 156 |
|
|---|
| 157 | { TFunctions }
|
|---|
| 158 |
|
|---|
| 159 | TFunctions = record
|
|---|
| 160 | Items: array of TFunction;
|
|---|
| 161 | procedure Add(Func: TFunction);
|
|---|
| 162 | function GetByName(Name: string): PFunction;
|
|---|
| 163 | function GetLast: PFunction;
|
|---|
| 164 | end;
|
|---|
| 165 |
|
|---|
| 166 | TExecutionParams = record
|
|---|
| 167 | Items: array of TGetValue;
|
|---|
| 168 | end;
|
|---|
| 169 |
|
|---|
| 170 | TExecution = record
|
|---|
| 171 | Func: PFunction;
|
|---|
| 172 | Parameters: TExecutionParams;
|
|---|
| 173 | end;
|
|---|
| 174 |
|
|---|
| 175 | TProgramCode = record
|
|---|
| 176 | Name: string;
|
|---|
| 177 | Variables: TVariables;
|
|---|
| 178 | Constants: TConstants;
|
|---|
| 179 | Types: TTypes;
|
|---|
| 180 | Functions: TFunctions;
|
|---|
| 181 | BeginEnd: TBeginEnd;
|
|---|
| 182 | end;
|
|---|
| 183 | PProgramCode = ^TProgramCode;
|
|---|
| 184 |
|
|---|
| 185 | function VariableCreate(Name: string; DataType: PType): TVariable;
|
|---|
| 186 | function FunctionCreate(Name: string; DataType: PType): TFunction;
|
|---|
| 187 | function TypeCreate(Name: string; BaseType: TBaseType): TType;
|
|---|
| 188 | function FunctionParameterCreate(Name: string; DataType: PType; Output: Boolean = False): TFunctionParameter;
|
|---|
| 189 |
|
|---|
| 190 | var
|
|---|
| 191 | OperatorString: array[TOperator] of string = ('', '+', '-', 'and', 'or', 'not',
|
|---|
| 192 | '=', '<>');
|
|---|
| 193 |
|
|---|
| 194 | const
|
|---|
| 195 | OperatorPrecedence: array[0..6] of TOperator = (opNot, opAnd, opOr, opAdd,
|
|---|
| 196 | opSubtract, opEqual, opNotEqual);
|
|---|
| 197 |
|
|---|
| 198 |
|
|---|
| 199 | implementation
|
|---|
| 200 |
|
|---|
| 201 | function VariableCreate(Name: string; DataType: PType): TVariable;
|
|---|
| 202 | begin
|
|---|
| 203 | Result.Name := Name;
|
|---|
| 204 | Result.DataType := DataType;
|
|---|
| 205 | end;
|
|---|
| 206 |
|
|---|
| 207 | function FunctionCreate(Name: string; DataType: PType): TFunction;
|
|---|
| 208 | begin
|
|---|
| 209 | Result.Name := Name;
|
|---|
| 210 | Result.ReturnType := DataType;
|
|---|
| 211 | end;
|
|---|
| 212 |
|
|---|
| 213 | function TypeCreate(Name: string; BaseType:TBaseType): TType;
|
|---|
| 214 | begin
|
|---|
| 215 | Result.Name := Name;
|
|---|
| 216 | Result.BaseType := BaseType;
|
|---|
| 217 | end;
|
|---|
| 218 |
|
|---|
| 219 | function FunctionParameterCreate(Name: string; DataType: PType; Output: Boolean = False): TFunctionParameter;
|
|---|
| 220 | begin
|
|---|
| 221 | Result.Name := Name;
|
|---|
| 222 | Result.DataType := DataType;
|
|---|
| 223 | Result.Output := Output;
|
|---|
| 224 | end;
|
|---|
| 225 |
|
|---|
| 226 | { TBeginEnd }
|
|---|
| 227 |
|
|---|
| 228 | procedure TBeginEnd.Add;
|
|---|
| 229 | begin
|
|---|
| 230 | SetLength(Commands, Length(Commands) + 1);
|
|---|
| 231 | end;
|
|---|
| 232 |
|
|---|
| 233 | function TBeginEnd.GetLast: PCommand;
|
|---|
| 234 | begin
|
|---|
| 235 | Result := @Commands[Length(Commands) - 1];
|
|---|
| 236 | end;
|
|---|
| 237 |
|
|---|
| 238 | { TConstants }
|
|---|
| 239 |
|
|---|
| 240 | procedure TConstants.Add(Constant: TConstant);
|
|---|
| 241 | begin
|
|---|
| 242 | SetLength(Items, Length(Items) + 1);
|
|---|
| 243 | Items[Length(Items) - 1] := Constant;
|
|---|
| 244 | Items[Length(Items) - 1].Index := Length(Items) - 1;
|
|---|
| 245 | end;
|
|---|
| 246 |
|
|---|
| 247 | function TConstants.GetByName(Name: string): PConstant;
|
|---|
| 248 | var
|
|---|
| 249 | I: Integer;
|
|---|
| 250 | begin
|
|---|
| 251 | I := 0;
|
|---|
| 252 | while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
|
|---|
| 253 | if I < Length(Items) then Result := @Items[I]
|
|---|
| 254 | else Result := nil;
|
|---|
| 255 | end;
|
|---|
| 256 |
|
|---|
| 257 | { TVariables }
|
|---|
| 258 |
|
|---|
| 259 | procedure TVariables.Add(Variable: TVariable);
|
|---|
| 260 | begin
|
|---|
| 261 | SetLength(Items, Length(Items) + 1);
|
|---|
| 262 | Items[Length(Items) - 1] := Variable;
|
|---|
| 263 | Items[Length(Items) - 1].Index := Length(Items) - 1;
|
|---|
| 264 | end;
|
|---|
| 265 |
|
|---|
| 266 | function TVariables.GetByName(Name: string): PVariable;
|
|---|
| 267 | var
|
|---|
| 268 | I: Integer;
|
|---|
| 269 | begin
|
|---|
| 270 | I := 0;
|
|---|
| 271 | while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
|
|---|
| 272 | if I < Length(Items) then Result := @Items[I]
|
|---|
| 273 | else Result := nil;
|
|---|
| 274 | end;
|
|---|
| 275 |
|
|---|
| 276 | { TFunctionParameters }
|
|---|
| 277 |
|
|---|
| 278 | procedure TFunctionParameters.Add(Param: TFunctionParameter);
|
|---|
| 279 | begin
|
|---|
| 280 | SetLength(Items, Length(Items) + 1);
|
|---|
| 281 | Items[Length(Items) - 1] := Param;
|
|---|
| 282 | end;
|
|---|
| 283 |
|
|---|
| 284 | { TTypes }
|
|---|
| 285 |
|
|---|
| 286 | procedure TTypes.Add(DataType: TType);
|
|---|
| 287 | begin
|
|---|
| 288 | SetLength(Items, Length(Items) + 1);
|
|---|
| 289 | Items[Length(Items) - 1] := DataType;
|
|---|
| 290 | end;
|
|---|
| 291 |
|
|---|
| 292 | function TTypes.GetByName(Name: string): PType;
|
|---|
| 293 | var
|
|---|
| 294 | I: Integer;
|
|---|
| 295 | begin
|
|---|
| 296 | I := 0;
|
|---|
| 297 | while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
|
|---|
| 298 | if I < Length(Items) then Result := @Items[I]
|
|---|
| 299 | else Result := nil;
|
|---|
| 300 | end;
|
|---|
| 301 |
|
|---|
| 302 | function TTypes.GetLast: PType;
|
|---|
| 303 | begin
|
|---|
| 304 | Result := @Items[Length(Items) - 1];
|
|---|
| 305 | end;
|
|---|
| 306 |
|
|---|
| 307 | { TFunctions }
|
|---|
| 308 |
|
|---|
| 309 | procedure TFunctions.Add(Func: TFunction);
|
|---|
| 310 | begin
|
|---|
| 311 | SetLength(Items, Length(Items) + 1);
|
|---|
| 312 | Items[Length(Items) - 1] := Func;
|
|---|
| 313 | end;
|
|---|
| 314 |
|
|---|
| 315 | function TFunctions.GetByName(Name: string): PFunction;
|
|---|
| 316 | var
|
|---|
| 317 | I: Integer;
|
|---|
| 318 | begin
|
|---|
| 319 | I := 0;
|
|---|
| 320 | while (I < Length(Items)) and (Items[I].Name <> Name) do I := I + 1;
|
|---|
| 321 | if I < Length(Items) then Result := @Items[I]
|
|---|
| 322 | else Result := nil;
|
|---|
| 323 | end;
|
|---|
| 324 |
|
|---|
| 325 | function TFunctions.GetLast: PFunction;
|
|---|
| 326 | begin
|
|---|
| 327 | Result := @Items[Length(Items) - 1];
|
|---|
| 328 | end;
|
|---|
| 329 |
|
|---|
| 330 | end.
|
|---|
| 331 |
|
|---|