Changeset 202 for branches/interpreter2
- Timestamp:
- Apr 17, 2020, 12:09:15 AM (5 years ago)
- Location:
- branches/interpreter2
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/interpreter2/Test.pas
r200 r202 1 // Line comment 1 2 program Test; 2 3 var 3 A; 4 B; 4 A: string; 5 B: string; 6 X: string; 7 I: Integer; 5 8 const 6 C = 1;9 C: Integer = 1; 7 10 begin 8 A := 2; 9 B := C; 11 X := 'A' + 'B'; 12 WriteLn(X); 13 A := IntToStr(2); 14 B := IntToStr(C); 10 15 A := B; 11 if A then begin 16 17 // If-Then-Else 18 if A = '2' then begin 12 19 WriteLn('DoThen'); 13 20 end else WriteLn('DoElse'); 14 21 15 A := ''; 16 while A do begin 17 WriteLn(A); 22 // While-Do 23 I := 5; 24 while I <> 0 do begin 25 WriteLn(IntToStr(I)); 26 I := I - 1; 27 end; 28 29 // For-To-Do 30 for I := 0 to 5 do begin 31 WriteLn(IntToStr(I)); 18 32 end; 19 33 34 // Begin-End 20 35 begin 21 36 WriteLn('Hello World!'); -
branches/interpreter2/UExecutor.pas
r201 r202 9 9 10 10 type 11 TExecutorFunctions = class; 12 11 13 TExecutorVariable = class 12 14 Variable: TVariable; 13 Value: string;15 Value: TValue; 14 16 end; 15 17 … … 21 23 end; 22 24 23 TExecutorFunctionCallback = function(Params: array of string): string of object; 25 { TExecutorType } 26 27 TExecutorType = class 28 TypeRef: TType; 29 Functions: TExecutorFunctions; 30 constructor Create; 31 destructor Destroy; override; 32 end; 33 34 { TExecutorTypes } 35 36 TExecutorTypes = class(TObjectList) 37 function SearchByType(TypeRef: TType): TExecutorType; 38 function AddNew(TypeRef: TType): TExecutorType; 39 end; 40 41 TExecutorFunctionCallback = function(Params: array of TValue): TValue of object; 24 42 25 43 TExecutorFunction = class … … 39 57 TExecutorBlock = class 40 58 Parent: TExecutorBlock; 59 Types: TExecutorTypes; 41 60 Variables: TExecutorVariables; 42 61 Functions: TExecutorFunctions; 43 62 function GetFunction(FunctionDef: TFunction): TExecutorFunction; 63 function GetType(TypeDef: TType): TExecutorType; 64 function GetVariable(Variable: TVariable): TExecutorVariable; 65 function GetTypeFunction(TypeDef: TType; FunctionDef: TFunction): TExecutorFunction; overload; 66 function GetTypeFunction(TypeDef: TType; FunctionName: string): TExecutorFunction; overload; 44 67 constructor Create; 45 68 destructor Destroy; override; … … 54 77 FOnOutput: TOutputEvent; 55 78 SystemBlock: TExecutorBlock; 56 function ExecuteWriteLn(Params: array of string): string; 57 function ExecuteWrite(Params: array of string): string; 79 function ExecuteWriteLn(Params: array of TValue): TValue; 80 function ExecuteWrite(Params: array of TValue): TValue; 81 function ExecuteIntToStr(Params: array of TValue): TValue; 82 function ExecuteStrToInt(Params: array of TValue): TValue; 83 function ExecuteStringAssign(Params: array of TValue): TValue; 84 function ExecuteStringAdd(Params: array of TValue): TValue; 85 function ExecuteStringEqual(Params: array of TValue): TValue; 86 function ExecuteStringNotEqual(Params: array of TValue): TValue; 87 function ExecuteIntegerAssign(Params: array of TValue): TValue; 88 function ExecuteIntegerAdd(Params: array of TValue): TValue; 89 function ExecuteIntegerSub(Params: array of TValue): TValue; 90 function ExecuteIntegerEqual(Params: array of TValue): TValue; 91 function ExecuteIntegerNotEqual(Params: array of TValue): TValue; 58 92 procedure InitExecutorBlock(ExecutorBlock: TExecutorBlock; Block: TBlock); 59 93 public … … 64 98 procedure ExecuteIfThenElse(Block: TExecutorBlock; IfThenElse: TIfThenElse); 65 99 procedure ExecuteWhileDo(Block: TExecutorBlock; WhileDo: TWhileDo); 100 procedure ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo); 66 101 procedure ExecuteBlock(ParentBlock: TExecutorBlock;Block: TBlock); 67 function ExecuteFunctionCall(Block: TExecutorBlock; FunctionCall: TFunctionCall): string;102 function ExecuteFunctionCall(Block: TExecutorBlock; FunctionCall: TFunctionCall): TValue; 68 103 procedure ExecuteAssignment(Block: TExecutorBlock; Assignment: TAssignment); 69 function ExecuteExpression(Block: TExecutorBlock; Expression: TExpression): string; 104 function ExecuteExpression(Block: TExecutorBlock; Expression: TExpression): TValue; 105 function ExecuteExpressionOperation(Block: TExecutorBlock; Expression: TExpressionOperation): TValue; 106 function ExecuteExpressionOperand(Block: TExecutorBlock; Expression: TExpressionOperand): TValue; 70 107 procedure Run; 71 108 procedure Output(Text: string); … … 75 112 76 113 implementation 114 115 { TExecutorType } 116 117 constructor TExecutorType.Create; 118 begin 119 Functions := TExecutorFunctions.Create; 120 end; 121 122 destructor TExecutorType.Destroy; 123 begin 124 Functions.Free; 125 inherited Destroy; 126 end; 127 128 { TExecutorTypes } 129 130 function TExecutorTypes.SearchByType(TypeRef: TType): TExecutorType; 131 var 132 I: Integer; 133 begin 134 I := 0; 135 while (I < Count) and (TExecutorType(Items[I]).TypeRef <> TypeRef) do Inc(I); 136 if I < Count then Result := TExecutorType(Items[I]) 137 else Result := nil; 138 end; 139 140 function TExecutorTypes.AddNew(TypeRef: TType): TExecutorType; 141 begin 142 Result := TExecutorType.Create; 143 Result.TypeRef := TypeRef; 144 Add(Result); 145 end; 77 146 78 147 { TExecutorFunctions } … … 124 193 end; 125 194 195 function TExecutorBlock.GetType(TypeDef: TType): TExecutorType; 196 begin 197 Result := Types.SearchByType(TypeDef); 198 if not Assigned(Result) and Assigned(Parent) then 199 Result := Parent.GetType(TypeDef); 200 end; 201 202 function TExecutorBlock.GetVariable(Variable: TVariable): TExecutorVariable; 203 begin 204 Result := Variables.SearchByVariable(Variable); 205 if not Assigned(Result) and Assigned(Parent) then 206 Result := Parent.GetVariable(Variable); 207 end; 208 209 function TExecutorBlock.GetTypeFunction(TypeDef: TType; FunctionDef: TFunction 210 ): TExecutorFunction; 211 var 212 ExecutorType: TExecutorType; 213 begin 214 ExecutorType := GetType(TypeDef); 215 Result := ExecutorType.Functions.SearchByFunction(FunctionDef); 216 end; 217 218 function TExecutorBlock.GetTypeFunction(TypeDef: TType; FunctionName: string 219 ): TExecutorFunction; 220 begin 221 Result := GetTypeFunction(TypeDef, TypeDef.Functions.SearchByName(FunctionName)); 222 end; 223 126 224 constructor TExecutorBlock.Create; 127 225 begin 226 Types := TExecutorTypes.Create; 128 227 Variables := TExecutorVariables.Create; 129 228 Functions := TExecutorFunctions.Create; … … 134 233 Variables.Free; 135 234 Functions.Free; 235 Types.Free; 136 236 inherited Destroy; 137 237 end; … … 139 239 { TExecutor } 140 240 141 function TExecutor.ExecuteWriteLn(Params: array of string): string;241 function TExecutor.ExecuteWriteLn(Params: array of TValue): TValue; 142 242 var 143 243 I: Integer; 144 244 Text: string; 145 245 begin 146 Result := '';246 Result := nil; 147 247 Text := ''; 148 248 for I := 0 to Length(Params) - 1 do 149 Text := Text + Params[I];249 Text := Text + TValueString(Params[I]).Value; 150 250 Output(Text + LineEnding); 151 251 end; 152 252 153 function TExecutor.ExecuteWrite(Params: array of string): string;253 function TExecutor.ExecuteWrite(Params: array of TValue): TValue; 154 254 var 155 255 I: Integer; 156 256 Text: string; 157 257 begin 158 Result := '';258 Result := nil; 159 259 Text := ''; 160 260 for I := 0 to Length(Params) - 1 do 161 Text := Text + Params[I];261 Text := Text + TValueString(Params[I]).Value; 162 262 Output(Text); 163 263 end; 164 264 265 function TExecutor.ExecuteIntToStr(Params: array of TValue): TValue; 266 begin 267 Result := TValueString.Create; 268 TValueString(Result).Value := IntToStr(TValueInteger(Params[0]).Value); 269 end; 270 271 function TExecutor.ExecuteStrToInt(Params: array of TValue): TValue; 272 begin 273 Result := TValueInteger.Create; 274 TValueInteger(Result).Value := StrToInt(TValueString(Params[0]).Value); 275 end; 276 277 function TExecutor.ExecuteStringAssign(Params: array of TValue): TValue; 278 begin 279 Result := TValueString.Create; 280 TValueString(Result).Value := TValueString(Params[0]).Value; 281 end; 282 283 function TExecutor.ExecuteStringAdd(Params: array of TValue): TValue; 284 begin 285 Result := TValueString.Create; 286 TValueString(Result).Value := TValueString(Params[0]).Value + TValueString(Params[1]).Value; 287 end; 288 289 function TExecutor.ExecuteStringEqual(Params: array of TValue): TValue; 290 begin 291 Result := TValueBoolean.Create; 292 TValueBoolean(Result).Value := TValueString(Params[0]).Value = TValueString(Params[1]).Value; 293 end; 294 295 function TExecutor.ExecuteStringNotEqual(Params: array of TValue): TValue; 296 begin 297 Result := TValueBoolean.Create; 298 TValueBoolean(Result).Value := TValueString(Params[0]).Value <> TValueString(Params[1]).Value; 299 end; 300 301 function TExecutor.ExecuteIntegerAssign(Params: array of TValue): TValue; 302 begin 303 Result := TValueInteger.Create; 304 TValueInteger(Result).Value := TValueInteger(Params[0]).Value; 305 end; 306 307 function TExecutor.ExecuteIntegerAdd(Params: array of TValue): TValue; 308 begin 309 Result := TValueInteger.Create; 310 TValueInteger(Result).Value := TValueInteger(Params[0]).Value + TValueInteger(Params[1]).Value; 311 end; 312 313 function TExecutor.ExecuteIntegerSub(Params: array of TValue): TValue; 314 begin 315 Result := TValueInteger.Create; 316 TValueInteger(Result).Value := TValueInteger(Params[0]).Value - TValueInteger(Params[1]).Value; 317 end; 318 319 function TExecutor.ExecuteIntegerEqual(Params: array of TValue): TValue; 320 begin 321 Result := TValueBoolean.Create; 322 TValueBoolean(Result).Value := TValueInteger(Params[0]).Value = TValueInteger(Params[1]).Value; 323 end; 324 325 function TExecutor.ExecuteIntegerNotEqual(Params: array of TValue): TValue; 326 begin 327 Result := TValueBoolean.Create; 328 TValueBoolean(Result).Value := TValueInteger(Params[0]).Value <> TValueInteger(Params[1]).Value; 329 end; 330 165 331 procedure TExecutor.InitExecutorBlock(ExecutorBlock: TExecutorBlock; Block: TBlock); 166 332 var 167 333 I: Integer; 334 J: Integer; 168 335 ExecutorFunction: TExecutorFunction; 169 begin 336 ExecutorType: TExecutorType; 337 begin 338 for I := 0 to Block.Types.Count - 1 do begin 339 ExecutorType := ExecutorBlock.Types.AddNew(TType(Block.Types[I])); 340 for J := 0 to ExecutorType.TypeRef.Functions.Count - 1 do begin 341 ExecutorFunction := ExecutorType.Functions.AddNew(TFunction(ExecutorType.TypeRef.Functions[J])); 342 if ExecutorType.TypeRef.Name = 'string' then begin 343 if ExecutorFunction.FunctionDef.Name = '_Assign' then begin 344 ExecutorFunction.Callback := ExecuteStringAssign; 345 end else 346 if ExecutorFunction.FunctionDef.Name = '_Add' then begin 347 ExecutorFunction.Callback := ExecuteStringAdd; 348 end else 349 if ExecutorFunction.FunctionDef.Name = '_Equal' then begin 350 ExecutorFunction.Callback := ExecuteStringEqual; 351 end; 352 if ExecutorFunction.FunctionDef.Name = '_NotEqual' then begin 353 ExecutorFunction.Callback := ExecuteStringNotEqual; 354 end; 355 end; 356 if ExecutorType.TypeRef.Name = 'Integer' then begin 357 if ExecutorFunction.FunctionDef.Name = '_Assign' then begin 358 ExecutorFunction.Callback := ExecuteIntegerAssign; 359 end else 360 if ExecutorFunction.FunctionDef.Name = '_Add' then begin 361 ExecutorFunction.Callback := ExecuteIntegerAdd; 362 end else 363 if ExecutorFunction.FunctionDef.Name = '_Sub' then begin 364 ExecutorFunction.Callback := ExecuteIntegerSub; 365 end else 366 if ExecutorFunction.FunctionDef.Name = '_Equal' then begin 367 ExecutorFunction.Callback := ExecuteIntegerEqual; 368 end else 369 if ExecutorFunction.FunctionDef.Name = '_NotEqual' then begin 370 ExecutorFunction.Callback := ExecuteIntegerNotEqual; 371 end; 372 end; 373 end; 374 end; 170 375 for I := 0 to Block.Variables.Count - 1 do 171 376 ExecutorBlock.Variables.AddNew(TVariable(Block.Variables[I])); 172 377 for I := 0 to Block.Functions.Count - 1 do begin 173 378 ExecutorFunction := ExecutorBlock.Functions.AddNew(TFunction(Block.Functions[I])); 174 if ExecutorFunction.FunctionDef.Name = 'Write' then ExecutorFunction.Callback := ExecuteWrite 175 else if ExecutorFunction.FunctionDef.Name = 'WriteLn' then ExecutorFunction.Callback := ExecuteWriteLn; 379 if ExecutorFunction.FunctionDef.Name = 'Write' then begin 380 ExecutorFunction.Callback := ExecuteWrite; 381 end else 382 if ExecutorFunction.FunctionDef.Name = 'WriteLn' then begin 383 ExecutorFunction.Callback := ExecuteWriteLn; 384 end; 385 if ExecutorFunction.FunctionDef.Name = 'IntToStr' then begin 386 ExecutorFunction.Callback := ExecuteIntToStr; 387 end else 388 if ExecutorFunction.FunctionDef.Name = 'StrToInt' then begin 389 ExecutorFunction.Callback := ExecuteStrToInt; 390 end; 176 391 end; 177 392 end; … … 200 415 else if Command is TIfThenElse then ExecuteIfThenElse(Block, TIfThenElse(Command)) 201 416 else if Command is TWhileDo then ExecuteWhileDo(Block, TWhileDo(Command)) 417 else if Command is TForToDo then ExecuteForToDo(Block, TForToDo(Command)) 202 418 else raise Exception.Create('Unsupported command type'); 203 419 end; … … 206 422 IfThenElse: TIfThenElse); 207 423 var 208 Value: string;424 Value: TValue; 209 425 begin 210 426 Value := ExecuteExpression(Block, IfThenElse.Expression); 211 if Value <> '' then ExecuteCommand(Block, IfThenElse.CommandThen) 212 else ExecuteCommand(Block, IfThenElse.CommandElse); 427 if Value is TValueBoolean then begin 428 if TValueBoolean(Value).Value then ExecuteCommand(Block, IfThenElse.CommandThen) 429 else ExecuteCommand(Block, IfThenElse.CommandElse); 430 end else raise Exception.Create('Expected boolean value.'); 213 431 end; 214 432 215 433 procedure TExecutor.ExecuteWhileDo(Block: TExecutorBlock; WhileDo: TWhileDo); 216 434 var 217 Value: string;435 Value: TValue; 218 436 begin 219 437 while True do begin 220 438 Value := ExecuteExpression(Block, WhileDo.Expression); 221 if Value <> '' then Continue 222 else Break; 439 if Value is TValueBoolean then begin 440 if not TValueBoolean(Value).Value then Break; 441 ExecuteCommand(Block, WhileDo.Command); 442 end else raise Exception.Create('Expected boolean value.'); 443 end; 444 end; 445 446 procedure TExecutor.ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo); 447 var 448 Value: TValue; 449 Variable: TExecutorVariable; 450 Limit: TValue; 451 begin 452 Variable := Block.GetVariable(ForToDo.VariableRef); 453 Variable.Value := ExecuteExpression(Block, ForToDo.ExpressionFrom); 454 Limit := ExecuteExpression(Block, ForToDo.ExpressionTo); 455 while True do begin 456 ExecuteCommand(Block, ForToDo.Command); 457 TValueInteger(Variable.Value).Value := TValueInteger(Variable.Value).Value + 1; 458 if TValueInteger(Variable.Value).Value > TValueInteger(Limit).Value then Break; 223 459 end; 224 460 end; … … 236 472 237 473 function TExecutor.ExecuteFunctionCall(Block: TExecutorBlock; 238 FunctionCall: TFunctionCall): string;474 FunctionCall: TFunctionCall): TValue; 239 475 var 240 476 ExecutorFunction: TExecutorFunction; 241 Params: array of string;242 I: Integer; 243 begin 244 Result := '';477 Params: array of TValue; 478 I: Integer; 479 begin 480 Result := nil; 245 481 ExecutorFunction := Block.GetFunction(FunctionCall.FunctionDef); 246 482 if Assigned(ExecutorFunction) then begin 247 483 SetLength(Params, FunctionCall.Params.Count); 248 for I := 0 to FunctionCall.Params.Count - 1 do 484 for I := 0 to FunctionCall.Params.Count - 1 do begin 249 485 Params[I] := ExecuteExpression(Block, TExpression(FunctionCall.Params[0])); 486 end; 250 487 Result := ExecutorFunction.Callback(Params); 251 488 end else raise Exception.Create('No executor for ' + FunctionCall.FunctionDef.Name + ' function.'); … … 255 492 Assignment: TAssignment); 256 493 var 257 Value: string;494 Value: TValue; 258 495 Variable: TExecutorVariable; 496 ExecutorFunction: TExecutorFunction; 497 Params: array of TValue; 259 498 begin 260 499 Value := ExecuteExpression(Block, Assignment.Expression); 261 Variable := Block.Variables.SearchByVariable(Assignment.Variable); 262 Variable.Value := Value; 500 Variable := Block.GetVariable(Assignment.Variable); 501 ExecutorFunction := Block.GetTypeFunction(Assignment.Variable.TypeRef, '_Assign'); 502 if Assignment.Variable.TypeRef = Assignment.Expression.GetType then begin; 503 SetLength(Params, 1); 504 Params[0] := Value; 505 Variable.Value := ExecutorFunction.Callback(Params); 506 end else raise Exception('Assignment result type is ' + Variable.Variable.TypeRef.Name + 507 ' but value is ' + Assignment.Expression.GetType.Name + '.'); 263 508 end; 264 509 265 510 function TExecutor.ExecuteExpression(Block: TExecutorBlock; 266 Expression: TExpression): string; 511 Expression: TExpression): TValue; 512 begin 513 if Expression is TExpressionOperation then 514 Result := ExecuteExpressionOperation(Block, TExpressionOperation(Expression)) 515 else 516 if Expression is TExpressionOperand then 517 Result := ExecuteExpressionOperand(Block, TExpressionOperand(Expression)) 518 else raise Exception.Create('Unknown expression class.'); 519 end; 520 521 function TExecutor.ExecuteExpressionOperation(Block: TExecutorBlock; 522 Expression: TExpressionOperation): TValue; 523 var 524 I: Integer; 525 Value: TValue; 526 ExecutorFunction: TExecutorFunction; 527 Params: array of TValue; 528 FuncName: string; 529 begin 530 if Expression.Operation = eoAdd then FuncName := '_Add' 531 else if Expression.Operation = eoSub then FuncName := '_Sub' 532 else if Expression.Operation = eoEqual then FuncName := '_Equal' 533 else if Expression.Operation = eoNotEqual then FuncName := '_NotEqual' 534 else raise Exception.Create('Unsupported operation type.'); 535 536 ExecutorFunction := Block.GetTypeFunction(Expression.TypeRef, FuncName); 537 Result := Expression.TypeRef.ValueClass.Create; 538 539 SetLength(Params, Expression.Items.Count); 540 for I := 0 to Expression.Items.Count - 1 do begin 541 Value := ExecuteExpression(Block, TExpression(Expression.Items[I])); 542 Params[I] := Value; 543 end; 544 Result := ExecutorFunction.Callback(Params); 545 end; 546 547 function TExecutor.ExecuteExpressionOperand(Block: TExecutorBlock; 548 Expression: TExpressionOperand): TValue; 267 549 begin 268 550 if Assigned(Expression.VariableRef) then begin … … 274 556 if Assigned(Expression.FunctionCall) then begin 275 557 Result := ExecuteFunctionCall(Block, Expression.FunctionCall); 276 end ;558 end else raise Exception.Create('Unsupported exception operand type.'); 277 559 end; 278 560 -
branches/interpreter2/UFormMain.lfm
r201 r202 13 13 OnShow = FormShow 14 14 LCLVersion = '2.0.2.0' 15 object MemoSource: TMemo16 Left = 2417 Height = 67218 Top = 6419 Width = 67120 Font.Name = 'Liberation Mono'21 ParentFont = False22 ScrollBars = ssAutoBoth23 TabOrder = 024 end25 15 object MemoLog: TMemo 26 16 Left = 24 … … 30 20 ReadOnly = True 31 21 ScrollBars = ssAutoBoth 32 TabOrder = 122 TabOrder = 0 33 23 end 34 24 object MemoOutput: TMemo … … 40 30 ParentFont = False 41 31 ScrollBars = ssAutoBoth 42 TabOrder = 232 TabOrder = 1 43 33 end 44 34 object ButtonCompile: TButton … … 49 39 Caption = 'Compile' 50 40 OnClick = ButtonCompileClick 51 TabOrder = 341 TabOrder = 2 52 42 end 53 43 object Label1: TLabel … … 74 64 Caption = 'Run' 75 65 OnClick = ButtonRunClick 66 TabOrder = 3 67 end 68 inline SynEditSource: TSynEdit 69 Left = 24 70 Height = 673 71 Top = 64 72 Width = 672 73 Font.Height = -20 74 Font.Name = 'Liberation Mono' 75 Font.Pitch = fpFixed 76 Font.Quality = fqNonAntialiased 77 ParentColor = False 78 ParentFont = False 76 79 TabOrder = 4 80 Gutter.Width = 85 81 Gutter.MouseActions = <> 82 RightGutter.Width = 0 83 RightGutter.MouseActions = <> 84 Highlighter = SynFreePascalSyn1 85 Keystrokes = < 86 item 87 Command = ecUp 88 ShortCut = 38 89 end 90 item 91 Command = ecSelUp 92 ShortCut = 8230 93 end 94 item 95 Command = ecScrollUp 96 ShortCut = 16422 97 end 98 item 99 Command = ecDown 100 ShortCut = 40 101 end 102 item 103 Command = ecSelDown 104 ShortCut = 8232 105 end 106 item 107 Command = ecScrollDown 108 ShortCut = 16424 109 end 110 item 111 Command = ecLeft 112 ShortCut = 37 113 end 114 item 115 Command = ecSelLeft 116 ShortCut = 8229 117 end 118 item 119 Command = ecWordLeft 120 ShortCut = 16421 121 end 122 item 123 Command = ecSelWordLeft 124 ShortCut = 24613 125 end 126 item 127 Command = ecRight 128 ShortCut = 39 129 end 130 item 131 Command = ecSelRight 132 ShortCut = 8231 133 end 134 item 135 Command = ecWordRight 136 ShortCut = 16423 137 end 138 item 139 Command = ecSelWordRight 140 ShortCut = 24615 141 end 142 item 143 Command = ecPageDown 144 ShortCut = 34 145 end 146 item 147 Command = ecSelPageDown 148 ShortCut = 8226 149 end 150 item 151 Command = ecPageBottom 152 ShortCut = 16418 153 end 154 item 155 Command = ecSelPageBottom 156 ShortCut = 24610 157 end 158 item 159 Command = ecPageUp 160 ShortCut = 33 161 end 162 item 163 Command = ecSelPageUp 164 ShortCut = 8225 165 end 166 item 167 Command = ecPageTop 168 ShortCut = 16417 169 end 170 item 171 Command = ecSelPageTop 172 ShortCut = 24609 173 end 174 item 175 Command = ecLineStart 176 ShortCut = 36 177 end 178 item 179 Command = ecSelLineStart 180 ShortCut = 8228 181 end 182 item 183 Command = ecEditorTop 184 ShortCut = 16420 185 end 186 item 187 Command = ecSelEditorTop 188 ShortCut = 24612 189 end 190 item 191 Command = ecLineEnd 192 ShortCut = 35 193 end 194 item 195 Command = ecSelLineEnd 196 ShortCut = 8227 197 end 198 item 199 Command = ecEditorBottom 200 ShortCut = 16419 201 end 202 item 203 Command = ecSelEditorBottom 204 ShortCut = 24611 205 end 206 item 207 Command = ecToggleMode 208 ShortCut = 45 209 end 210 item 211 Command = ecCopy 212 ShortCut = 16429 213 end 214 item 215 Command = ecPaste 216 ShortCut = 8237 217 end 218 item 219 Command = ecDeleteChar 220 ShortCut = 46 221 end 222 item 223 Command = ecCut 224 ShortCut = 8238 225 end 226 item 227 Command = ecDeleteLastChar 228 ShortCut = 8 229 end 230 item 231 Command = ecDeleteLastChar 232 ShortCut = 8200 233 end 234 item 235 Command = ecDeleteLastWord 236 ShortCut = 16392 237 end 238 item 239 Command = ecUndo 240 ShortCut = 32776 241 end 242 item 243 Command = ecRedo 244 ShortCut = 40968 245 end 246 item 247 Command = ecLineBreak 248 ShortCut = 13 249 end 250 item 251 Command = ecSelectAll 252 ShortCut = 16449 253 end 254 item 255 Command = ecCopy 256 ShortCut = 16451 257 end 258 item 259 Command = ecBlockIndent 260 ShortCut = 24649 261 end 262 item 263 Command = ecLineBreak 264 ShortCut = 16461 265 end 266 item 267 Command = ecInsertLine 268 ShortCut = 16462 269 end 270 item 271 Command = ecDeleteWord 272 ShortCut = 16468 273 end 274 item 275 Command = ecBlockUnindent 276 ShortCut = 24661 277 end 278 item 279 Command = ecPaste 280 ShortCut = 16470 281 end 282 item 283 Command = ecCut 284 ShortCut = 16472 285 end 286 item 287 Command = ecDeleteLine 288 ShortCut = 16473 289 end 290 item 291 Command = ecDeleteEOL 292 ShortCut = 24665 293 end 294 item 295 Command = ecUndo 296 ShortCut = 16474 297 end 298 item 299 Command = ecRedo 300 ShortCut = 24666 301 end 302 item 303 Command = ecGotoMarker0 304 ShortCut = 16432 305 end 306 item 307 Command = ecGotoMarker1 308 ShortCut = 16433 309 end 310 item 311 Command = ecGotoMarker2 312 ShortCut = 16434 313 end 314 item 315 Command = ecGotoMarker3 316 ShortCut = 16435 317 end 318 item 319 Command = ecGotoMarker4 320 ShortCut = 16436 321 end 322 item 323 Command = ecGotoMarker5 324 ShortCut = 16437 325 end 326 item 327 Command = ecGotoMarker6 328 ShortCut = 16438 329 end 330 item 331 Command = ecGotoMarker7 332 ShortCut = 16439 333 end 334 item 335 Command = ecGotoMarker8 336 ShortCut = 16440 337 end 338 item 339 Command = ecGotoMarker9 340 ShortCut = 16441 341 end 342 item 343 Command = ecSetMarker0 344 ShortCut = 24624 345 end 346 item 347 Command = ecSetMarker1 348 ShortCut = 24625 349 end 350 item 351 Command = ecSetMarker2 352 ShortCut = 24626 353 end 354 item 355 Command = ecSetMarker3 356 ShortCut = 24627 357 end 358 item 359 Command = ecSetMarker4 360 ShortCut = 24628 361 end 362 item 363 Command = ecSetMarker5 364 ShortCut = 24629 365 end 366 item 367 Command = ecSetMarker6 368 ShortCut = 24630 369 end 370 item 371 Command = ecSetMarker7 372 ShortCut = 24631 373 end 374 item 375 Command = ecSetMarker8 376 ShortCut = 24632 377 end 378 item 379 Command = ecSetMarker9 380 ShortCut = 24633 381 end 382 item 383 Command = EcFoldLevel1 384 ShortCut = 41009 385 end 386 item 387 Command = EcFoldLevel2 388 ShortCut = 41010 389 end 390 item 391 Command = EcFoldLevel3 392 ShortCut = 41011 393 end 394 item 395 Command = EcFoldLevel4 396 ShortCut = 41012 397 end 398 item 399 Command = EcFoldLevel5 400 ShortCut = 41013 401 end 402 item 403 Command = EcFoldLevel6 404 ShortCut = 41014 405 end 406 item 407 Command = EcFoldLevel7 408 ShortCut = 41015 409 end 410 item 411 Command = EcFoldLevel8 412 ShortCut = 41016 413 end 414 item 415 Command = EcFoldLevel9 416 ShortCut = 41017 417 end 418 item 419 Command = EcFoldLevel0 420 ShortCut = 41008 421 end 422 item 423 Command = EcFoldCurrent 424 ShortCut = 41005 425 end 426 item 427 Command = EcUnFoldCurrent 428 ShortCut = 41003 429 end 430 item 431 Command = EcToggleMarkupWord 432 ShortCut = 32845 433 end 434 item 435 Command = ecNormalSelect 436 ShortCut = 24654 437 end 438 item 439 Command = ecColumnSelect 440 ShortCut = 24643 441 end 442 item 443 Command = ecLineSelect 444 ShortCut = 24652 445 end 446 item 447 Command = ecTab 448 ShortCut = 9 449 end 450 item 451 Command = ecShiftTab 452 ShortCut = 8201 453 end 454 item 455 Command = ecMatchBracket 456 ShortCut = 24642 457 end 458 item 459 Command = ecColSelUp 460 ShortCut = 40998 461 end 462 item 463 Command = ecColSelDown 464 ShortCut = 41000 465 end 466 item 467 Command = ecColSelLeft 468 ShortCut = 40997 469 end 470 item 471 Command = ecColSelRight 472 ShortCut = 40999 473 end 474 item 475 Command = ecColSelPageDown 476 ShortCut = 40994 477 end 478 item 479 Command = ecColSelPageBottom 480 ShortCut = 57378 481 end 482 item 483 Command = ecColSelPageUp 484 ShortCut = 40993 485 end 486 item 487 Command = ecColSelPageTop 488 ShortCut = 57377 489 end 490 item 491 Command = ecColSelLineStart 492 ShortCut = 40996 493 end 494 item 495 Command = ecColSelLineEnd 496 ShortCut = 40995 497 end 498 item 499 Command = ecColSelEditorTop 500 ShortCut = 57380 501 end 502 item 503 Command = ecColSelEditorBottom 504 ShortCut = 57379 505 end> 506 MouseActions = <> 507 MouseTextActions = <> 508 MouseSelActions = <> 509 VisibleSpecialChars = [vscSpace, vscTabAtLast] 510 SelectedColor.BackPriority = 50 511 SelectedColor.ForePriority = 50 512 SelectedColor.FramePriority = 50 513 SelectedColor.BoldPriority = 50 514 SelectedColor.ItalicPriority = 50 515 SelectedColor.UnderlinePriority = 50 516 SelectedColor.StrikeOutPriority = 50 517 BracketHighlightStyle = sbhsBoth 518 BracketMatchColor.Background = clNone 519 BracketMatchColor.Foreground = clNone 520 BracketMatchColor.Style = [fsBold] 521 FoldedCodeColor.Background = clNone 522 FoldedCodeColor.Foreground = clGray 523 FoldedCodeColor.FrameColor = clGray 524 MouseLinkColor.Background = clNone 525 MouseLinkColor.Foreground = clBlue 526 LineHighlightColor.Background = clNone 527 LineHighlightColor.Foreground = clNone 528 inline SynLeftGutterPartList1: TSynGutterPartList 529 object SynGutterMarks1: TSynGutterMarks 530 Width = 36 531 MouseActions = <> 532 end 533 object SynGutterLineNumber1: TSynGutterLineNumber 534 Width = 25 535 MouseActions = <> 536 MarkupInfo.Background = clBtnFace 537 MarkupInfo.Foreground = clNone 538 DigitCount = 2 539 ShowOnlyLineNumbersMultiplesOf = 1 540 ZeroStart = False 541 LeadingZeros = False 542 end 543 object SynGutterChanges1: TSynGutterChanges 544 Width = 6 545 MouseActions = <> 546 ModifiedColor = 59900 547 SavedColor = clGreen 548 end 549 object SynGutterSeparator1: TSynGutterSeparator 550 Width = 3 551 MouseActions = <> 552 MarkupInfo.Background = clWhite 553 MarkupInfo.Foreground = clGray 554 end 555 object SynGutterCodeFolding1: TSynGutterCodeFolding 556 Width = 15 557 MouseActions = <> 558 MarkupInfo.Background = clNone 559 MarkupInfo.Foreground = clGray 560 MouseActionsExpanded = <> 561 MouseActionsCollapsed = <> 562 end 563 end 564 end 565 object SynFreePascalSyn1: TSynFreePascalSyn 566 Enabled = False 567 CompilerMode = pcmObjFPC 568 NestedComments = True 569 left = 608 570 top = 128 77 571 end 78 572 end -
branches/interpreter2/UFormMain.pas
r201 r202 6 6 7 7 uses 8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, USource; 8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, 9 SynHighlighterPas, SynEdit, USource; 9 10 10 11 type … … 17 18 Label1: TLabel; 18 19 Label2: TLabel; 19 MemoSource: TMemo;20 20 MemoLog: TMemo; 21 21 MemoOutput: TMemo; 22 SynEditSource: TSynEdit; 23 SynFreePascalSyn1: TSynFreePascalSyn; 22 24 procedure ButtonCompileClick(Sender: TObject); 23 25 procedure ButtonRunClick(Sender: TObject); … … 53 55 if not Initialized then begin 54 56 Initialized := True; 55 MemoSource.Lines.LoadFromFile('Test.pas');57 SynEditSource.Lines.LoadFromFile('Test.pas'); 56 58 ButtonRun.Click; 57 59 end; … … 95 97 Parser := TParser.Create; 96 98 Parser.OnError := InterpreterError; 97 Parser.Source := MemoSource.Lines.Text;99 Parser.Source := SynEditSource.Lines.Text; 98 100 Parser.Parse; 99 101 if Assigned(Prog) then Prog.Free; -
branches/interpreter2/UParser.pas
r201 r202 21 21 function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; 22 22 function ParseBlock(ParentBlock: TBlock; out Block: TBlock): Boolean; 23 function Parse VarBlock(Block: TBlock): Boolean;24 function Parse ConstBlock(Block: TBlock): Boolean;23 function ParseBlockVar(Block: TBlock): Boolean; 24 function ParseBlockConst(Block: TBlock): Boolean; 25 25 function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean; 26 26 function ParseExpression(Block: TBlock; out Expression: TExpression): Boolean; 27 function ParseExpressionOperation(Block: TBlock; out ExpressionOperation: TExpressionOperation): Boolean; 28 function ParseExpressionOperand(Block: TBlock; out ExpressionOperand: TExpressionOperand): Boolean; 29 function ParseConstant(Block: TBlock; out ConstantRef: TConstant): Boolean; 30 function ParseVariable(Block: TBlock; out VariableRef: TVariable): Boolean; 27 31 function ParseIfThenElse(Block: TBlock; out IfThenElse: TIfThenElse): Boolean; 28 32 function ParseWhileDo(Block: TBlock; out WhileDo: TWhileDo): Boolean; 33 function ParseForToDo(Block: TBlock; out ForToDo: TForToDo): Boolean; 29 34 procedure TokenizerError(Pos: TPoint; Text: string); 30 35 procedure InitSystemBlock(Block: TBlock); … … 73 78 FunctionDef: TFunction; 74 79 Expression: TExpression; 80 I: Integer; 75 81 begin 76 82 LastPos := Tokenizer.Pos; … … 80 86 if Assigned(FunctionDef) then begin 81 87 FunctionCall := TFunctionCall.Create; 82 FunctionCall.FunctionDef := functionDef;88 FunctionCall.FunctionDef := FunctionDef; 83 89 if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin 84 90 Tokenizer.Expect('(', tkSpecialSymbol); 85 if ParseExpression(Block, Expression) then begin 86 FunctionCall.Params.Add(Expression); 87 end else Error('Exprected function parameter.'); 91 for I := 0 to FunctionDef.Params.Count - 1 do begin 92 if I > 0 then Tokenizer.Expect(',', tkSpecialSymbol); 93 if ParseExpression(Block, Expression) then begin 94 if Expression.GetType = TFunctionParameter(FunctionDef.Params[I]).TypeRef then 95 FunctionCall.Params.Add(Expression) 96 else Error('Function parameter mismatch.'); 97 end else Error('Expected function parameter.'); 98 end; 88 99 Tokenizer.Expect(')', tkSpecialSymbol); 89 100 end; … … 106 117 IfThenElse: TIfThenElse; 107 118 WhileDo: TWhileDo; 119 ForToDo: TForToDo; 108 120 begin 109 121 if ParseIfThenElse(Block, IfThenElse) then begin … … 114 126 Result := True; 115 127 Command := WhileDo; 128 end else 129 if ParseForToDo(Block, ForToDo) then begin 130 Result := True; 131 Command := ForToDo; 116 132 end else 117 133 if ParseBeginEnd(Block, BeginEnd) then begin … … 163 179 Block := TBlock.Create; 164 180 Block.Parent := ParentBlock; 165 Parse VarBlock(Block);166 Parse ConstBlock(Block);181 ParseBlockVar(Block); 182 ParseBlockConst(Block); 167 183 if ParseBeginEnd(Block, BeginEnd) then begin 168 184 Result := True; … … 172 188 end; 173 189 174 function TParser.Parse VarBlock(Block: TBlock): Boolean;190 function TParser.ParseBlockVar(Block: TBlock): Boolean; 175 191 var 176 192 Token: TToken; 177 193 Variable: TVariable; 194 TypeRef: TType; 178 195 begin 179 196 if Tokenizer.CheckNext('var', tkKeyword) then begin … … 188 205 Variable.Name := Token.Text; 189 206 Block.Variables.Add(Variable); 207 Tokenizer.Expect(':', tkSpecialSymbol); 208 Token := Tokenizer.GetNext; 209 if Token.Kind = tkIdentifier then begin 210 TypeRef := Block.GetType(Token.Text); 211 if Assigned(TypeRef) then begin 212 Variable.TypeRef := TypeRef; 213 end else Error('Type ' + Token.Text + ' not found.'); 214 end; 190 215 end else Error('Variable ' + Token.Text + ' redefined.'); 191 216 Tokenizer.Expect(';', tkSpecialSymbol); … … 198 223 end; 199 224 200 function TParser.Parse ConstBlock(Block: TBlock): Boolean;225 function TParser.ParseBlockConst(Block: TBlock): Boolean; 201 226 var 202 227 Token: TToken; 203 228 Constant: TConstant; 229 TypeRef: TType; 204 230 begin 205 231 if Tokenizer.CheckNext('const', tkKeyword) then begin … … 214 240 Constant.Name := Token.Text; 215 241 Block.Constants.Add(Constant); 242 Tokenizer.Expect(':', tkSpecialSymbol); 243 Token := Tokenizer.GetNext; 244 if Token.Kind = tkIdentifier then begin 245 TypeRef := Block.GetType(Token.Text); 246 if Assigned(TypeRef) then begin 247 Constant.TypeRef := TypeRef; 248 end else Error('Type ' + Token.Text + ' not found.'); 249 end; 216 250 Tokenizer.Expect('=', tkSpecialSymbol); 217 251 Token := Tokenizer.GetNext; 218 if (Token.Kind = tkNumber) or (Token.Kind = tkString) then 219 Constant.Value := Token.Text 220 else Error('Expected string or number.'); 252 if Token.Kind = tkNumber then begin 253 Constant.Value := TValueInteger.Create; 254 TValueInteger(Constant.Value).Value := StrToInt(Token.Text); 255 end else 256 if Token.Kind = tkString then begin 257 Constant.Value := TValueString.Create; 258 TValueString(Constant.Value).Value := Token.Text; 259 end else Error('Expected string or number.'); 221 260 end else Error('Constant ' + Token.Text + ' redefined.'); 222 261 Tokenizer.Expect(';', tkSpecialSymbol); … … 239 278 if Token.Kind = tkIdentifier then begin 240 279 Result := True; 241 Variable := Block. Variables.SearchByName(Token.Text);280 Variable := Block.GetVariable(Token.Text); 242 281 if Assigned(Variable) then begin 243 282 Result := True; … … 246 285 Tokenizer.Expect(':=', tkSpecialSymbol); 247 286 if ParseExpression(Block, Expression) then begin 248 Assignment.Expression.Free; 249 Assignment.Expression := Expression; 287 if Expression.GetType = Variable.TypeRef then begin 288 Assignment.Expression.Free; 289 Assignment.Expression := Expression; 290 end else begin 291 Result := False; 292 Error('Assignment type mismatch.'); 293 end; 250 294 end; 295 if not Result then Assignment.Free; 251 296 end else Error('Variable ' + Token.Text + ' not defined.'); 252 297 end; … … 256 301 ): Boolean; 257 302 var 303 ExpressionOperation: TExpressionOperation; 304 ExpressionOperand: TExpressionOperand; 305 begin 306 Result := False; 307 if ParseExpressionOperation(Block, ExpressionOperation) then begin 308 Result := True; 309 Expression := ExpressionOperation; 310 end else 311 if ParseExpressionOperand(Block, ExpressionOperand) then begin 312 Result := True; 313 Expression := ExpressionOperand; 314 end; 315 end; 316 317 function TParser.ParseExpressionOperation(Block: TBlock; out 318 ExpressionOperation: TExpressionOperation): Boolean; 319 var 320 Operand: TExpressionOperand; 321 Token: TToken; 322 Expression: TExpression; 323 LastPos: TTokenizerPos; 324 begin 325 Result := False; 326 LastPos := Tokenizer.Pos; 327 if ParseExpressionOperand(Block, Operand) then begin 328 Token := Tokenizer.GetNext; 329 if (Token.Kind = tkSpecialSymbol) and Tokenizer.IsOperator(Token.Text) then begin 330 Result := True; 331 ExpressionOperation := TExpressionOperation.Create; 332 ExpressionOperation.TypeRef := Operand.GetType; 333 if Token.Text = '+' then ExpressionOperation.Operation := eoAdd 334 else if Token.Text = '-' then ExpressionOperation.Operation := eoSub 335 else if Token.Text = '=' then ExpressionOperation.Operation := eoEqual 336 else if Token.Text = '<>' then ExpressionOperation.Operation := eoNotEqual 337 else Error('Unsupported operator ' + Token.Text); 338 ExpressionOperation.Items.Add(Operand); 339 if ParseExpression(Block, Expression) then begin 340 if Expression.GetType = Operand.GetType then 341 ExpressionOperation.Items.Add(Expression) 342 else Error('Expression operands needs to be same type.'); 343 end else Error('Missing operand.'); 344 end; 345 end; 346 if not Result then Tokenizer.Pos := LastPos; 347 end; 348 349 function TParser.ParseExpressionOperand(Block: TBlock; out 350 ExpressionOperand: TExpressionOperand): Boolean; 351 var 258 352 Variable: TVariable; 259 353 Constant: TConstant; 260 Token: TToken; 261 begin 262 Result := False; 354 FunctionCall: TFunctionCall; 355 begin 356 Result := False; 357 if ParseFunctionCall(Block, FunctionCall) then begin 358 Result := True; 359 ExpressionOperand := TExpressionOperand.Create; 360 ExpressionOperand.FunctionCall := FunctionCall; 361 ExpressionOperand.OperandType := otFunctionCall; 362 end else 363 if ParseConstant(Block, Constant) then begin 364 Result := True; 365 ExpressionOperand := TExpressionOperand.Create; 366 ExpressionOperand.ConstantRef := Constant; 367 ExpressionOperand.OperandType := otConstant; 368 end else 369 if ParseVariable(Block, Variable) then begin 370 Result := True; 371 ExpressionOperand := TExpressionOperand.Create; 372 ExpressionOperand.VariableRef := Variable; 373 ExpressionOperand.OperandType := otVariable; 374 end else Error('Expected expression operand.'); 375 end; 376 377 function TParser.ParseConstant(Block: TBlock; out ConstantRef: TConstant 378 ): Boolean; 379 var 380 LastPos: TTokenizerPos; 381 Token: TToken; 382 begin 383 Result := False; 384 LastPos := Tokenizer.Pos; 263 385 Token := Tokenizer.GetNext; 264 if Token.Kind = tkIdentifier then begin 265 Variable := Block.Variables.SearchByName(Token.Text);266 if Assigned( Variable) then begin386 if Token.Kind = tkIdentifier then begin; 387 ConstantRef := Block.GetConstant(Token.Text); 388 if Assigned(ConstantRef) then begin 267 389 Result := True; 268 Expression := TExpression.Create;269 Expression.VariableRef := Variable;270 end else begin271 Constant := Block.Constants.SearchByName(Token.Text);272 if Assigned(Constant) then begin273 Result := True;274 Expression := TExpression.Create;275 Expression.ConstantRef := Constant;276 end;277 390 end; 278 391 end else 279 392 if Token.Kind = tkNumber then begin 280 393 Result := True; 281 Constant := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count));282 Constant .Value := Token.Text;283 Expression := TExpression.Create;284 Expression.ConstantRef := Constant;394 ConstantRef := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count)); 395 ConstantRef.TypeRef := Block.GetType('Integer'); 396 ConstantRef.Value := TValueInteger.Create; 397 TValueInteger(ConstantRef.Value).Value := StrToInt(Token.Text); 285 398 end else 286 399 if Token.Kind = tkString then begin 287 400 Result := True; 288 Constant := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count)); 289 Constant.Value := Token.Text; 290 Expression := TExpression.Create; 291 Expression.ConstantRef := Constant; 292 end; 401 ConstantRef := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count)); 402 ConstantRef.TypeRef := Block.GetType('string'); 403 ConstantRef.Value := TValueString.Create; 404 TValueString(ConstantRef.Value).Value := Token.Text; 405 end; 406 if not Result then Tokenizer.Pos := LastPos; 407 end; 408 409 function TParser.ParseVariable(Block: TBlock; out VariableRef: TVariable 410 ): Boolean; 411 var 412 LastPos: TTokenizerPos; 413 Token: TToken; 414 begin 415 Result := False; 416 LastPos := Tokenizer.Pos; 417 Token := Tokenizer.GetNext; 418 if Token.Kind = tkIdentifier then begin; 419 VariableRef := Block.GetVariable(Token.Text); 420 if Assigned(VariableRef) then begin 421 Result := True; 422 end; 423 end; 424 if not Result then Tokenizer.Pos := LastPos; 293 425 end; 294 426 … … 345 477 end; 346 478 479 function TParser.ParseForToDo(Block: TBlock; out ForToDo: TForToDo): Boolean; 480 var 481 Expression: TExpression; 482 VariableRef: TVariable; 483 Command: TCommand; 484 begin 485 Result := False; 486 if Tokenizer.CheckNext('for', tkKeyword) then begin 487 Tokenizer.Expect('for', tkKeyword); 488 Result := True; 489 ForToDo := TForToDo.Create; 490 if ParseVariable(Block, VariableRef) then begin 491 ForToDo.VariableRef := VariableRef; 492 Tokenizer.Expect(':=', tkSpecialSymbol); 493 if ParseExpression(Block, Expression) then begin 494 ForToDo.ExpressionFrom.Free; 495 ForToDo.ExpressionFrom := Expression; 496 Tokenizer.Expect('to', tkKeyword); 497 if ParseExpression(Block, Expression) then begin 498 ForToDo.ExpressionTo.Free; 499 ForToDo.ExpressionTo := Expression; 500 Tokenizer.Expect('do', tkKeyword); 501 if ParseCommand(Block, Command) then begin 502 ForToDo.Command.Free; 503 ForToDo.Command := Command; 504 end else Error('Expected command.'); 505 end else Error('Expected expression.'); 506 end else Error('Expected expression.'); 507 end else Error('Expected control variable.'); 508 end; 509 end; 510 347 511 procedure TParser.TokenizerError(Pos: TPoint; Text: string); 348 512 begin … … 352 516 353 517 procedure TParser.InitSystemBlock(Block: TBlock); 354 begin 355 Block.Functions.AddNew('WriteLn'); 356 Block.Functions.AddNew('Write'); 518 var 519 TypeBoolean: TType; 520 TypeString: TType; 521 TypeInteger: TType; 522 begin 523 TypeBoolean := Block.Types.AddNew('Boolean'); 524 with TypeBoolean do begin 525 ValueClass := TValueBoolean; 526 with Functions.AddNew('_Assign') do begin 527 Params.AddNew('Source', TypeBoolean); 528 ResultType := TypeBoolean; 529 end; 530 with Functions.AddNew('_Equal') do begin 531 Params.AddNew('A', TypeBoolean); 532 Params.AddNew('B', TypeBoolean); 533 ResultType := TypeBoolean; 534 end; 535 end; 536 TypeString := Block.Types.AddNew('string'); 537 with TypeString do begin 538 ValueClass := TValueString; 539 with Functions.AddNew('_Assign') do begin 540 Params.AddNew('Source', TypeString); 541 ResultType := TypeString; 542 end; 543 with Functions.AddNew('_Add') do begin 544 Params.AddNew('A', TypeString); 545 Params.AddNew('B', TypeString); 546 ResultType := TypeString; 547 end; 548 with Functions.AddNew('_Equal') do begin 549 Params.AddNew('A', TypeString); 550 Params.AddNew('B', TypeString); 551 ResultType := TypeBoolean; 552 end; 553 with Functions.AddNew('_NotEqual') do begin 554 Params.AddNew('A', TypeString); 555 Params.AddNew('B', TypeString); 556 ResultType := TypeBoolean; 557 end; 558 end; 559 TypeInteger := Block.Types.AddNew('Integer'); 560 with TypeInteger do begin 561 ValueClass := TValueInteger; 562 with Functions.AddNew('_Assign') do begin 563 Params.AddNew('Source', TypeInteger); 564 ResultType := TypeInteger; 565 end; 566 with Functions.AddNew('_Add') do begin 567 Params.AddNew('A', TypeInteger); 568 Params.AddNew('B', TypeInteger); 569 ResultType := TypeInteger; 570 end; 571 with Functions.AddNew('_Sub') do begin 572 Params.AddNew('A', TypeInteger); 573 Params.AddNew('B', TypeInteger); 574 ResultType := TypeInteger; 575 end; 576 with Functions.AddNew('_Equal') do begin 577 Params.AddNew('A', TypeInteger); 578 Params.AddNew('B', TypeInteger); 579 ResultType := TypeBoolean; 580 end; 581 with Functions.AddNew('_NotEqual') do begin 582 Params.AddNew('A', TypeInteger); 583 Params.AddNew('B', TypeInteger); 584 ResultType := TypeBoolean; 585 end; 586 end; 587 with Block.Functions.AddNew('IntToStr') do begin 588 Params.AddNew('Value', TypeInteger); 589 ResultType := TypeString; 590 end; 591 with Block.Functions.AddNew('StrToInt') do begin 592 Params.AddNew('Value', TypeString); 593 ResultType := TypeInteger; 594 end; 595 with Block.Functions.AddNew('WriteLn') do begin 596 Params.AddNew('Text', TypeString); 597 end; 598 with Block.Functions.AddNew('Write') do begin 599 Params.AddNew('Text', TypeString); 600 end; 357 601 end; 358 602 -
branches/interpreter2/USource.pas
r201 r202 10 10 type 11 11 TExpressions = class; 12 TFunctions = class; 13 14 TValue = class 15 end; 16 17 TValueString = class(TValue) 18 Value: string; 19 end; 20 21 TValueInteger = class(TValue) 22 Value: Integer; 23 end; 24 25 TValueBoolean = class(TValue) 26 Value: Boolean; 27 end; 28 29 TValueClass = class of TValue; 30 31 { TType } 32 33 TType = class 34 Name: string; 35 Functions: TFunctions; 36 ValueClass: TValueClass; 37 constructor Create; 38 destructor Destroy; override; 39 end; 40 41 { TTypes } 42 43 TTypes = class(TObjectList) 44 function SearchByName(Name: string): TType; 45 function AddNew(Name: string): TType; 46 end; 12 47 13 48 TVariable = class 14 49 Name: string; 50 TypeRef: TType; 15 51 end; 16 52 … … 23 59 TConstant = class 24 60 Name: string; 25 Value: string; 61 TypeRef: TType; 62 Value: TValue; 26 63 end; 27 64 … … 33 70 end; 34 71 72 TFunctionParameter = class 73 Name: string; 74 TypeRef: TType; 75 end; 76 77 { TFunctionParameters } 78 79 TFunctionParameters = class(TObjectList) 80 function SearchByName(Name: string): TFunctionParameter; 81 function AddNew(Name: string; TypeRef: TType): TFunctionParameter; 82 end; 83 84 { TFunction } 85 35 86 TFunction = class 36 87 Name: string; 88 Params: TFunctionParameters; 89 ResultType: TType; 90 constructor Create; 91 destructor Destroy; override; 37 92 end; 38 93 … … 52 107 FunctionDef: TFunction; 53 108 Params: TExpressions; 54 ReturnValue: Boolean;55 109 constructor Create; 56 110 destructor Destroy; override; … … 66 120 end; 67 121 122 TExpressionOperator = (eoAdd, eoSub, eoMultiply, eoDivide, eoModulo, eoAnd, eoXor, 123 eoOr, eoShl, eoShr, eoEqual, eoNotEqual); 124 125 { TExpression } 126 68 127 TExpression = class 128 function GetType: TType; virtual; 129 end; 130 131 { TExpressionOperation } 132 133 TExpressionOperation = class(TExpression) 134 TypeRef: TType; 135 Operation: TExpressionOperator; 136 Items: TExpressions; 137 constructor Create; 138 destructor Destroy; override; 139 function GetType: TType; override; 140 end; 141 142 TExpressionOperandType = (otVariable, otConstant, otFunctionCall); 143 144 { TExpressionOperand } 145 146 TExpressionOperand = class(TExpression) 147 OperandType: TExpressionOperandType; 69 148 VariableRef: TVariable; 70 149 ConstantRef: TConstant; 71 150 FunctionCall: TFunctionCall; 151 function GetType: TType; override; 72 152 end; 73 153 … … 98 178 TWhileDo = class(TCommand) 99 179 Expression: TExpression; 180 Command: TCommand; 181 constructor Create; 182 destructor Destroy; override; 183 end; 184 185 { TForToDo } 186 187 TForToDo = class(TCommand) 188 VariableRef: TVariable; 189 ExpressionFrom: TExpression; 190 ExpressionTo: TExpression; 100 191 Command: TCommand; 101 192 constructor Create; … … 110 201 Constants: TConstants; 111 202 Functions: TFunctions; 203 Types: TTypes; 112 204 BeginEnd: TBeginEnd; 113 205 procedure Clear; 206 function GetType(Name: string): TType; 207 function GetConstant(Name: string): TConstant; 208 function GetVariable(Name: string): TVariable; 114 209 function GetFunction(Name: string): TFunction; 115 210 constructor Create; … … 130 225 implementation 131 226 227 { TForToDo } 228 229 constructor TForToDo.Create; 230 begin 231 ExpressionFrom := TExpression.Create; 232 ExpressionTo := TExpression.Create; 233 Command := TCommand.Create; 234 end; 235 236 destructor TForToDo.Destroy; 237 begin 238 Command.Free; 239 ExpressionTo.Free; 240 ExpressionFrom.Free; 241 inherited Destroy; 242 end; 243 244 { TExpression } 245 246 function TExpression.GetType: TType; 247 begin 248 Result := nil; 249 end; 250 251 { TExpressionOperand } 252 253 function TExpressionOperand.GetType: TType; 254 begin 255 if OperandType = otFunctionCall then Result := FunctionCall.FunctionDef.ResultType 256 else if OperandType = otConstant then Result := ConstantRef.TypeRef 257 else if OperandType = otVariable then Result := VariableRef.TypeRef 258 else raise Exception.Create('Unsupported operand type'); 259 end; 260 261 { TFunctionParameters } 262 263 function TFunctionParameters.SearchByName(Name: string): TFunctionParameter; 264 var 265 I: Integer; 266 begin 267 I := 0; 268 while (I < Count) and (TFunctionParameter(Items[I]).Name <> Name) do Inc(I); 269 if I < Count then Result := TFunctionParameter(Items[I]) 270 else Result := nil; 271 end; 272 273 function TFunctionParameters.AddNew(Name: string; TypeRef: TType): TFunctionParameter; 274 begin 275 Result := TFunctionParameter.Create; 276 Result.Name := Name; 277 Result.TypeRef := TypeRef; 278 Add(Result); 279 end; 280 281 { TFunction } 282 283 constructor TFunction.Create; 284 begin 285 Params := TFunctionParameters.Create; 286 end; 287 288 destructor TFunction.Destroy; 289 begin 290 Params.Free; 291 inherited Destroy; 292 end; 293 294 { TType } 295 296 constructor TType.Create; 297 begin 298 Functions := TFunctions.Create; 299 end; 300 301 destructor TType.Destroy; 302 begin 303 Functions.Free; 304 inherited Destroy; 305 end; 306 307 { TTypes } 308 309 function TTypes.SearchByName(Name: string): TType; 310 var 311 I: Integer; 312 begin 313 I := 0; 314 while (I < Count) and (TType(Items[I]).Name <> Name) do Inc(I); 315 if I < Count then Result := TType(Items[I]) 316 else Result := nil; 317 end; 318 319 function TTypes.AddNew(Name: string): TType; 320 begin 321 Result := TType.Create; 322 Result.Name := Name; 323 Add(Result); 324 end; 325 326 { TExpressionOperation } 327 328 constructor TExpressionOperation.Create; 329 begin 330 Items := TExpressions.Create; 331 end; 332 333 destructor TExpressionOperation.Destroy; 334 begin 335 Items.Free; 336 inherited Destroy; 337 end; 338 339 function TExpressionOperation.GetType: TType; 340 begin 341 Result := TypeRef; 342 end; 343 132 344 { TAssignment } 133 345 … … 247 459 Constants.Clear; 248 460 Variables.Clear; 461 Types.Clear; 462 end; 463 464 function TBlock.GetType(Name: string): TType; 465 begin 466 Result := Types.SearchByName(Name); 467 if not Assigned(Result) and Assigned(Parent) then 468 Result := Parent.Types.SearchByName(Name); 469 end; 470 471 function TBlock.GetConstant(Name: string): TConstant; 472 begin 473 Result := Constants.SearchByName(Name); 474 if not Assigned(Result) and Assigned(Parent) then 475 Result := Parent.Constants.SearchByName(Name); 476 end; 477 478 function TBlock.GetVariable(Name: string): TVariable; 479 begin 480 Result := Variables.SearchByName(Name); 481 if not Assigned(Result) and Assigned(Parent) then 482 Result := Parent.Variables.SearchByName(Name); 249 483 end; 250 484 … … 261 495 Variables := TVariables.Create; 262 496 Functions := TFunctions.Create; 497 Types := TTypes.Create; 263 498 BeginEnd := TBeginEnd.Create; 264 499 end; … … 267 502 begin 268 503 BeginEnd.Free; 504 Types.Free; 269 505 Variables.Free; 270 506 Constants.Free; -
branches/interpreter2/UTokenizer.pas
r200 r202 30 30 31 31 TTokenizerState = (tsNone, tsIdentifier, tsString, tsStringEnd, tsNumber, 32 tsSpecialSymbol );32 tsSpecialSymbol, tsLineComment); 33 33 34 34 { TTokenizer } … … 48 48 function IsSpecialSymbol2(Text: string): Boolean; 49 49 function IsIdentifier(Text: string): Boolean; 50 function IsOperator(Text: string): Boolean; 50 51 function IsKeyword(Text: string): Boolean; 51 52 procedure Init; 52 53 function GetNext: TToken; 53 function CheckNext(Text: string; Kind: TTokenKind = tkUnknown): Boolean;54 function CheckNext(Text: string; Kind: TTokenKind): Boolean; 54 55 function CheckNextKind(Kind: TTokenKind): Boolean; 55 procedure Expect(Text: string; Kind: TTokenKind = tkUnknown);56 procedure Expect(Text: string; Kind: TTokenKind); 56 57 procedure Error(Text: string); 57 58 property OnError: TErrorEvent read FOnError write FOnError; … … 109 110 begin 110 111 Result := (C = ';') or (C = '.') or (C = '(') or (C = ')') or (C = '=') or 111 (C = ':'); 112 (C = ':') or (C = '+') or (C = '-') or (C = ',') or (C = '/') or 113 (C = '<') or (C = '>'); 112 114 end; 113 115 114 116 function TTokenizer.IsSpecialSymbol2(Text: string): Boolean; 115 117 begin 116 Result := (Text = ':=') ;118 Result := (Text = ':=') or (Text = '//') or (Text = '<>'); 117 119 end; 118 120 … … 137 139 end; 138 140 141 function TTokenizer.IsOperator(Text: string): Boolean; 142 begin 143 Result := (Text = '+') or (Text = '-') or (Text = '=') or (Text = '<>'); 144 end; 145 139 146 function TTokenizer.IsKeyword(Text: string): Boolean; 140 147 begin 141 148 Result := (Text = 'begin') or (Text = 'end') or (Text = 'program') or 142 149 (Text = 'var') or (Text = 'const') or (Text = 'if') or (Text = 'then') or 143 (Text = 'else') or (Text = 'while') or (Text = 'do'); 150 (Text = 'else') or (Text = 'while') or (Text = 'do') or (Text = 'for') or 151 (Text = 'to'); 144 152 end; 145 153 … … 229 237 end; 230 238 end else 239 if State = tsLineComment then begin 240 if C = #10 then begin 241 State := tsNone; 242 end else Pos.Increment; 243 end else 231 244 if State = tsSpecialSymbol then begin 232 245 if IsSpecialSymbol2(Result.Text + C) then begin 233 246 Result.Text := Result.Text + C; 234 247 Pos.Increment; 235 Break; 248 if Result.Text = '//' then begin 249 Result.Text := ''; 250 State := tsLineComment; 251 end else Break; 236 252 end else begin 237 253 Break; … … 242 258 end; 243 259 244 function TTokenizer.CheckNext(Text: string; Kind: TTokenKind = tkUnknown): Boolean;260 function TTokenizer.CheckNext(Text: string; Kind: TTokenKind): Boolean; 245 261 var 246 262 LastPos: TTokenizerPos; … … 264 280 end; 265 281 266 procedure TTokenizer.Expect(Text: string; Kind: TTokenKind = tkUnknown);282 procedure TTokenizer.Expect(Text: string; Kind: TTokenKind); 267 283 var 268 284 Token: TToken; -
branches/interpreter2/interpreter.lpi
r201 r202 63 63 <Modes Count="0"/> 64 64 </RunParams> 65 <RequiredPackages Count=" 1">65 <RequiredPackages Count="2"> 66 66 <Item1> 67 <PackageName Value="SynEdit"/> 68 </Item1> 69 <Item2> 67 70 <PackageName Value="LCL"/> 68 </Item 1>71 </Item2> 69 72 </RequiredPackages> 70 73 <Units Count="7">
Note:
See TracChangeset
for help on using the changeset viewer.