- Timestamp:
- Jun 20, 2008, 9:55:04 AM (17 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Example.pas
r10 r11 3 3 A: Byte; 4 4 begin 5 A := 10; 5 A := 'a' + (10 + 2) * 3 xor 10 / 2; 6 while A < 10 do A := A + 1; 6 7 end; -
trunk/UMainForm.dfm
r10 r11 22 22 Top = 8 23 23 Width = 401 24 Height = 5 9324 Height = 529 25 25 Font.Charset = DEFAULT_CHARSET 26 26 Font.Color = clWindowText … … 42 42 end 43 43 object Memo2: TMemo 44 Left = 41 644 Left = 415 45 45 Top = 8 46 46 Width = 321 47 Height = 593 47 Height = 529 48 Font.Charset = DEFAULT_CHARSET 49 Font.Color = clWindowText 50 Font.Height = -13 51 Font.Name = 'Lucida Console' 52 Font.Style = [] 53 ParentFont = False 48 54 ScrollBars = ssBoth 49 55 TabOrder = 2 50 56 end 57 object Memo3: TMemo 58 Left = 8 59 Top = 543 60 Width = 728 61 Height = 66 62 ScrollBars = ssBoth 63 TabOrder = 3 64 end 51 65 end -
trunk/UMainForm.pas
r10 r11 12 12 TModuleType = (mdProgram, mdUnit, mdLibrary, mdPackage); 13 13 14 TInstruction = (inJump, inConditionalJump, inExpressionEvaluation); 15 16 TNodeType = (ntNone, ntVariable, ntMethod, ntConstant, ntOperator); 17 14 18 TValue = array of Byte; 15 19 16 20 TCompiler = class; 21 TCommonBlock = class; 22 TTypeList = class; 23 TConstantList = class; 24 TVariableList = class; 25 TMethodList = class; 26 TExpression = class; 27 TOperationList = class; 17 28 18 29 TDevice = class 19 30 Family: string; 20 31 Memory: array[TMemoryType] of Integer; 32 end; 33 34 TCommonBlock = class 35 Name: string; 36 Parent: TCommonBlock; 37 Constants: TConstantList; 38 Types: TTypeList; 39 Variables: TVariableList; 40 Methods: TMethodList; 41 Operations: TOperationList; 42 procedure AllocateMemory; 43 constructor Create; virtual; 44 destructor Destroy; override; 45 procedure ParseDefinitions(Compiler: TCompiler); 46 function ParseExpression(Compiler: TCompiler): TExpression; 47 procedure ParseProgramCode(Compiler: TCompiler); 48 procedure ParseOperation(Compiler: TCompiler); 49 procedure GenerateAssembler(Compiler: TCompiler; LabelPrefix: string); 50 end; 51 52 TType = class 53 Parent: TTypeList; 54 Name: string; 55 Size: Integer; 56 UsedType: TType; 57 procedure Parse(Compiler: TCompiler); 58 end; 59 60 TTypeList = class(TList) 61 Parent: TCommonBlock; 62 procedure Parse(Compiler: TCompiler); 63 function Search(Name: string): TType; 64 end; 65 66 TConstant = class 67 Name: string; 68 ValueType: TType; 69 Value: TValue; 70 procedure Parse(Compiler: TCompiler); 71 end; 72 73 TConstantList = class(TList) 74 Parent: TCommonBlock; 75 function Search(Name: string): TConstant; 76 procedure Parse(Compiler: TCompiler); 77 end; 78 79 TVariable = class 80 Name: string; 81 ValueType: TType; 82 Value: TValue; 83 procedure Parse(Compiler: TCompiler); 84 end; 85 86 TVariableList = class(TList) 87 Parent: TCommonBlock; 88 procedure Parse(Compiler: TCompiler); 89 function Search(Name: string): TVariable; 90 end; 91 92 TExpression = class 93 NodeType: TNodeType; 94 Variable: TVariable; 95 Method: TMethod; 96 Value: TValue; 97 OperatorName: string; 98 SubItems: TList; // TList<TExpression> 99 Associated: Boolean; 100 constructor Create; 101 destructor Destroy; override; 102 procedure GenerateAssembler(Compiler: TCompiler; LabelPrefix: string); 103 end; 104 105 TOperation = class 106 Instruction: TInstruction; 107 ExpressionTree: TExpression; 108 GotoAddress: Integer; 109 Negative: Boolean; 110 end; 111 112 TOperationList = class(TList) 113 114 end; 115 116 TMethod = class(TCommonBlock) 117 Parameters: TList; // TList<TParameter> 118 ResultType: TType; 119 constructor Create; override; 120 destructor Destroy; override; 121 procedure Parse(Compiler: TCompiler); 122 end; 123 124 TMethodList = class(TList) 125 Parent: TCommonBlock; 126 procedure Parse(Compiler: TCompiler); 127 function Search(Name: string): TMethod; 128 end; 129 130 TModule = class(TCommonBlock) 131 ModuleType: TModuleType; 132 UsedModules: TList; // TList<TModule> 133 constructor Create; override; 134 destructor Destroy; override; 135 procedure Parse(Compiler: TCompiler); 136 private 137 procedure ParseUnit(Compiler: TCompiler); 138 procedure ParseProgram(Compiler: TCompiler); 21 139 end; 22 140 … … 27 145 destructor Destroy; override; 28 146 procedure Parse(Compiler: TCompiler); 29 end; 30 31 TType = class 32 Name: string; 33 Size: Integer; 34 end; 35 36 TTypeList = class(TList) 37 procedure Parse(Compiler: TCompiler); 38 end; 39 40 TConstant = class 41 Name: string; 42 ValueType: TType; 43 Value: TValue; 44 procedure Parse(Compiler: TCompiler); 45 end; 46 47 TConstantList = class(TList) 48 procedure Parse(Compiler: TCompiler); 49 end; 50 51 TVariable = class 52 Name: string; 53 ValueType: TType; 54 Value: TValue; 55 end; 56 57 TVariableList = class(TList) 58 procedure Parse(Compiler: TCompiler); 59 end; 60 61 TProgramCode = class 62 procedure Parse(Compiler: TCompiler); 63 end; 64 65 TMethod = class 66 Name: string; 67 Parameters: TList; // TList<TParameter> 68 Constants: TList; // TList<TConstant> 69 Types: TList; // TList<TType> 70 Variables: TList; // TList<TVariable> 71 ResultType: TType; 72 ProgramCode: TProgramCode; 73 constructor Create; 74 destructor Destroy; override; 75 procedure Parse(Compiler: TCompiler); 76 end; 77 78 TModule = class 79 Name: string; 80 ModuleType: TModuleType; 81 Constants: TList; // TList<TConstant> 82 Types: TList; // TList<TType> 83 Variables: TList; // TList<TVariable> 84 constructor Create; 85 destructor Destroy; override; 86 procedure Parse(Compiler: TCompiler); 87 procedure ParseDefinitions(Compiler: TCompiler); 88 private 89 procedure ParseUnit(Compiler: TCompiler); 90 procedure ParseProgram(Compiler: TCompiler); 147 procedure AllocateMemory; 148 procedure GenerateAssembler(Compiler: TCompiler); 149 end; 150 151 TAssemblerLine = class 152 LabelName: string; 153 Instruction: string; 154 Operand1: string; 155 Operand2: string; 156 SourceCode: string; 157 function AsString: string; 91 158 end; 92 159 … … 95 162 SourceCode: TStringList; 96 163 CodePosition: Integer; 97 Assemb erCode: TStringList;164 AssemblyCode: TList; // TList<TAssemblerLine> 98 165 ProgramCode: TProgram; 99 166 procedure ErrorMessage(Text: string); … … 106 173 function IsIdentificator(Text: string): Boolean; 107 174 function IsKeyword(Text: string): Boolean; 175 function IsOperator(Text: string): Boolean; 176 procedure GenerateAssemblyCode; 177 procedure AddInstruction(LabelName, Instruction, Operand1, Operand2: string); 108 178 public 109 179 constructor Create; … … 116 186 Button1: TButton; 117 187 Memo2: TMemo; 188 Memo3: TMemo; 118 189 procedure FormShow(Sender: TObject); 119 190 procedure FormClose(Sender: TObject; var Action: TCloseAction); … … 128 199 129 200 const 130 KeyWords: array[0.. 40] of string = ('program', 'unit', 'uses', 'begin', 'end',201 KeyWords: array[0..37] of string = ('program', 'unit', 'uses', 'begin', 'end', 131 202 'type', 'const', 'var', 'array', 'record', 'absolute', 'virtual', 'class', 132 203 'set', 'private', 'public', 'interface', 'implementation', 'finalization', 133 'initialization', 'for', 'while', 'if', 'case', 'of', ' as', 'in', 'is', 'pointer',204 'initialization', 'for', 'while', 'if', 'case', 'of', 'pointer', 134 205 'object', 'packed', 'procedure', 'function', 'to', 'do', 'downto', 'repeat', 135 206 'until', 'then', 'asm', 'else'); 207 Operators: array[0..22] of string = ('@', 'not', '*', 'and', '/', 'shl', 208 'shr', 'as', 'div', 'mod', 'or', 'xor', '-', '+', '=', '>', '<', '<>', '<=', 209 '>=', 'is', 'in', ':='); 210 136 211 var 137 212 MainForm: TMainForm; … … 142 217 143 218 procedure TMainForm.Button1Click(Sender: TObject); 219 var 220 I: Integer; 144 221 begin 145 222 Compiler.Compile(Memo1.Lines); 146 Memo2.Assign(Compiler.AssemberCode); 223 Memo2.Clear; 224 for I := 0 to Compiler.AssemblyCode.Count - 1 do 225 Memo2.Lines.Add(TAssemblerLine(Compiler.AssemblyCode[I]).AsString); 147 226 end; 148 227 … … 163 242 164 243 procedure TMainForm.FormShow(Sender: TObject); 244 var 245 I: Integer; 165 246 begin 166 247 Memo1.Lines.LoadFromFile('Example.pas'); 167 248 Compiler.Compile(Memo1.Lines); 249 Memo2.Clear; 250 for I := 0 to Compiler.AssemblyCode.Count - 1 do 251 Memo2.Lines.Add(TAssemblerLine(Compiler.AssemblyCode[I]).AsString); 252 168 253 end; 169 254 170 255 { TCompiler } 171 256 257 procedure TCompiler.AddInstruction(LabelName, Instruction, Operand1, 258 Operand2: string); 259 var 260 NewLine: TAssemblerLine; 261 begin 262 NewLine := TAssemblerLine.Create; 263 AssemblyCode.Add(NewLine); 264 NewLine.LabelName := LabelName; 265 NewLine.Instruction := Instruction; 266 NewLine.Operand1 := Operand1; 267 NewLine.Operand2 := Operand2; 268 end; 269 172 270 procedure TCompiler.Compile(SourceCode: TStrings); 173 271 begin 272 MainForm.Memo3.Clear; 174 273 Self.SourceCode.Assign(SourceCode); 175 274 CodePosition := 1; 176 275 ProgramCode.Parse(Self); 276 ProgramCode.AllocateMemory; 277 GenerateAssemblyCode; 177 278 end; 178 279 … … 180 281 begin 181 282 SourceCode := TStringList.Create; 182 Assemb erCode := TStringList.Create;283 AssemblyCode := TList.Create; 183 284 ProgramCode := TProgram.Create; 184 285 end; … … 187 288 begin 188 289 ProgramCode.Free; 189 Assemb erCode.Free;290 AssemblyCode.Free; 190 291 SourceCode.Free; 191 292 end; … … 193 294 procedure TCompiler.ErrorMessage(Text: string); 194 295 begin 195 ShowMessage(Text); 296 //ShowMessage(Text); 297 MainForm.Memo3.Lines.Add(Text); 196 298 end; 197 299 … … 202 304 end; 203 305 ReadCode; 306 end; 307 308 procedure TCompiler.GenerateAssemblyCode; 309 begin 310 ProgramCode.GenerateAssembler(Self); 204 311 end; 205 312 … … 221 328 for I := 0 to High(Keywords) do 222 329 if Keywords[I] = Text then 330 Result := True; 331 end; 332 333 function TCompiler.IsOperator(Text: string): Boolean; 334 var 335 I: Integer; 336 begin 337 Result := False; 338 for I := 0 to High(Operators) do 339 if Operators[I] = Text then 223 340 Result := True; 224 341 end; … … 274 391 end else 275 392 if Text[J] = '''' then begin 393 I := J + 1; 276 394 while not ((Text[I] = '''') and (Text[I + 1] <> '''')) do Inc(I); 277 Result := Copy(Text, J, I - J); 395 Inc(I); 396 Result := Copy(Text, J, I - J ); 278 397 end else 279 398 if (Text[J] in SpecChar) then begin … … 285 404 Break; 286 405 end; 406 I := J; 287 407 end; 288 408 if Result = '' then begin … … 292 412 end else begin 293 413 while IsAlphanumeric(Text[I]) do Inc(I); 294 Result := Copy(Text, J, I - J);414 Result := LowerCase(Copy(Text, J, I - J)); 295 415 end; 296 416 J := I; … … 322 442 constructor TMethod.Create; 323 443 begin 444 inherited; 324 445 Parameters := TList.Create; 325 Constants := TConstantList.Create;326 Types := TTypeList.Create;327 Variables := TVariableList.Create;328 446 ResultType := TType.Create; 329 447 end; … … 332 450 begin 333 451 Parameters.Free; 334 Constants.Free;335 Types.Free;336 Variables.Free;337 452 ResultType.Free; 453 inherited; 338 454 end; 339 455 … … 350 466 { TProgram } 351 467 468 procedure TProgram.AllocateMemory; 469 var 470 I: Integer; 471 begin 472 for I := 0 to Modules.Count - 1 do 473 TModule(Modules[I]).AllocateMemory; 474 end; 475 352 476 constructor TProgram.Create; 353 477 begin … … 355 479 Modules := TList.Create; 356 480 with TModule(Modules[Modules.Add(TModule.Create)]) do begin 357 Name := 'Main'; 481 Name := 'main'; 482 with TType(Types[Types.Add(TType.Create)]) do begin 483 Name := 'byte'; 484 Size := 1; 485 UsedType := nil; 486 end; 358 487 end; 359 488 end; … … 364 493 end; 365 494 495 procedure TProgram.GenerateAssembler(Compiler: TCompiler); 496 var 497 I: Integer; 498 begin 499 for I := 0 to Modules.Count - 1 do 500 TModule(Modules[I]).GenerateAssembler(Compiler, ''); 501 end; 502 366 503 procedure TProgram.Parse(Compiler: TCompiler); 367 504 begin … … 380 517 procedure TConstantList.Parse(Compiler: TCompiler); 381 518 begin 382 Compiler.Expect('const'); 383 while Compiler.IsIdentificator(Compiler.NextCode) do 384 TConstant(Items[Add(TConstant.Create)]).Parse(Compiler); 519 // Compiler.Expect('const'); 520 // while Compiler.IsIdentificator(Compiler.NextCode) do 521 // TConstant(Items[Add(TConstant.Create)]).Parse(Compiler); 522 end; 523 524 function TConstantList.Search(Name: string): TConstant; 525 var 526 I: Integer; 527 begin 528 I := 0; 529 while (I < Count) and (TConstant(Items[I]).Name <> Name) do Inc(I); 530 if I < Count then Result := Items[I] else begin 531 if Assigned(Parent.Parent) then Result := Parent.Parent.Constants.Search(Name) 532 else begin 533 Result := nil; 534 end; 535 end; 385 536 end; 386 537 … … 389 540 constructor TModule.Create; 390 541 begin 391 Constants := TConstantList.Create; 392 Types := TTypeList.Create; 393 Variables := TVariableList.Create; 542 inherited; 543 UsedModules := TList.Create; 394 544 end; 395 545 396 546 destructor TModule.Destroy; 397 547 begin 398 Constants.Destroy; 399 Types.Destroy; 400 Variables.Destroy; 548 UsedModules.Destroy; 401 549 inherited; 402 550 end; 403 551 404 552 procedure TModule.ParseProgram(Compiler: TCompiler); 553 var 554 Identifier: string; 405 555 begin 406 556 with Compiler do begin … … 411 561 Expect(';'); 412 562 end else Name := ''; 563 564 // Uses section 565 if NextCode = 'uses' then begin 566 Identifier := ReadCode; 567 while NextCode = ',' do begin 568 Identifier := ReadCode; 569 570 end; 571 end; 413 572 ParseDefinitions(Compiler); 414 573 end; … … 424 583 end; 425 584 426 procedure TModule.ParseDefinitions(Compiler: TCompiler); 585 procedure TCommonBlock.AllocateMemory; 586 begin 587 // for I := 0 to Variables - 1 do 588 589 end; 590 591 constructor TCommonBlock.Create; 592 begin 593 Constants := TConstantList.Create; 594 Constants.Parent := Self; 595 Types := TTypeList.Create; 596 Types.Parent := Self; 597 Variables := TVariableList.Create; 598 Variables.Parent := Self; 599 Methods := TMethodList.Create; 600 Methods.Parent := Self; 601 Operations := TOperationList.Create; 602 end; 603 604 destructor TCommonBlock.Destroy; 605 begin 606 Constants.Destroy; 607 Types.Destroy; 608 Variables.Destroy; 609 Methods.Destroy; 610 Operations.Destroy; 611 inherited; 612 end; 613 614 procedure TCommonBlock.GenerateAssembler(Compiler: TCompiler; LabelPrefix: string); 615 var 616 I: Integer; 617 begin 618 with Compiler do 619 for I := 0 to Operations.Count - 1 do 620 with TOperation(Operations[I]) do begin 621 case Instruction of 622 inJump: begin 623 AddInstruction('', 'JMP', Name + '_L' + IntToStr(GotoAddress), ''); 624 end; 625 inConditionalJump: begin 626 ExpressionTree.GenerateAssembler(Compiler, LabelPrefix + '_L' + IntToStr(GotoAddress)); 627 AddInstruction('', 'BRCS', Name + '_L' + IntToStr(GotoAddress), ''); 628 end; 629 inExpressionEvaluation: begin 630 ExpressionTree.GenerateAssembler(Compiler, Name + '_L' + IntToStr(GotoAddress)); 631 end; 632 end; 633 end; 634 end; 635 636 procedure TCommonBlock.ParseDefinitions(Compiler: TCompiler); 427 637 begin 428 638 with Compiler do begin 429 if NextCode = 'var' then TVariableList(Variables).Parse(Compiler) 430 else if NextCode = 'const' then TConstantList(Constants).Parse(Compiler) 431 else if NextCode = 'type' then TTypeList(Types).Parse(Compiler) 432 else ParseProgram(Compiler); 639 while NextCode <> '.' do begin 640 if NextCode = 'var' then TVariableList(Variables).Parse(Compiler) 641 else if NextCode = 'const' then TConstantList(Constants).Parse(Compiler) 642 else if NextCode = 'type' then TTypeList(Types).Parse(Compiler) 643 else begin 644 ParseProgramCode(Compiler); 645 Break; 646 end; 647 end; 648 end; 649 end; 650 651 function TCommonBlock.ParseExpression(Compiler: TCompiler): TExpression; 652 var 653 Identifier: string; 654 Variable: TVariable; 655 Method: TMethod; 656 Constant: TConstant; 657 // Brackets: Integer; 658 Expressions: TList; // TList<TExpression>; 659 I: Integer; 660 II: Integer; 661 begin 662 Expressions := TList.Create; 663 Expressions.Add(TExpression.Create); 664 with Compiler do begin 665 while ((NextCode <> ';') and (NextCode <> ',') and (not IsKeyWord(NextCode))) and 666 not (((NextCode = ')') or (NextCode = ']'))) do begin 667 Identifier := ReadCode; 668 if Identifier = '(' then begin 669 with TExpression(Expressions[Expressions.Count - 1]) do begin 670 SubItems[1] := ParseExpression(Compiler); 671 end; 672 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 673 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 674 end; 675 Expect(')'); 676 end else 677 if IsOperator(Identifier) then begin 678 TExpression(Expressions[Expressions.Count - 1]).OperatorName := Identifier; 679 TExpression(Expressions[Expressions.Count - 1]).NodeType := ntOperator; 680 end else 681 if IsIdentificator(Identifier) then begin 682 Variable := Variables.Search(Identifier); 683 if Assigned(Variable) then begin 684 with TExpression(Expressions[Expressions.Count - 1]) do begin 685 SubItems[1] := TExpression.Create; 686 TExpression(SubItems[1]).NodeType := ntVariable; 687 TExpression(SubItems[1]).Variable := Variable; 688 end; 689 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 690 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 691 end; 692 end else begin 693 Method := Methods.Search(Identifier); 694 if Assigned(Method) then begin 695 with TExpression(Expressions[Expressions.Count - 1]) do begin 696 SubItems[1] := TExpression.Create; 697 if NextCode = '(' then // Method with parameters 698 with TExpression(SubItems[1]) do begin 699 Expect('('); 700 SubItems.Add(ParseExpression(Compiler)); 701 while NextCode = ',' do begin 702 Expect(','); 703 SubItems.Add(ParseExpression(Compiler)); 704 end; 705 Expect(')'); 706 end; 707 TExpression(SubItems[1]).NodeType := ntMethod; 708 TExpression(SubItems[1]).Method := Method; 709 end; 710 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 711 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 712 end; 713 end else begin 714 Constant := Constants.Search(Identifier); 715 if Assigned(Constant) then begin 716 with TExpression(Expressions[Expressions.Count - 1]) do begin 717 SubItems[1] := TExpression.Create; 718 TExpression(SubItems[1]).NodeType := ntConstant; 719 TExpression(SubItems[1]).Value := Constant.Value; 720 end; 721 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 722 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 723 end; 724 end; 725 end; 726 end; 727 end else 728 begin 729 with TExpression(Expressions[Expressions.Count - 1]) do begin 730 SubItems[1] := TExpression.Create; 731 TExpression(SubItems[1]).NodeType := ntConstant; 732 733 if Identifier[1] = '''' then begin 734 SetLength(TExpression(SubItems[1]).Value, Length(Identifier)); 735 for I := 1 to Length(Identifier) do TExpression(SubItems[1]).Value[I - 1] := Byte(Identifier[I]); 736 end else begin 737 SetLength(TExpression(SubItems[1]).Value, 1); 738 TExpression(SubItems[1]).Value[0] := StrToInt(Identifier); 739 end; 740 end; 741 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 742 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 743 end; 744 end; 745 end; 746 747 // Build expression tree 748 for II := 0 to High(Operators) do begin 749 I := 1; 750 while (I < Expressions.Count - 1) do begin 751 if not TExpression(Expressions[I]).Associated and 752 (TExpression(Expressions[I]).OperatorName = Operators[II]) then begin 753 TExpression(Expressions[I]).Associated := True; 754 TExpression(Expressions[I - 1]).SubItems[1] := Expressions[I]; 755 TExpression(Expressions[I + 1]).SubItems[0] := Expressions[I]; 756 Expressions.Delete(I); 757 end else Inc(I); 758 end; 759 end; 760 end; 761 Result := TExpression(Expressions[0]).SubItems[1]; 762 TExpression(Expressions[0]).Destroy; 763 TExpression(Expressions[1]).Destroy; 764 Expressions.Destroy; 765 end; 766 767 procedure TCommonBlock.ParseOperation(Compiler: TCompiler); 768 var 769 Identifier: string; 770 Variable: TVariable; 771 Method: TMethod; 772 First: TOperation; 773 Second: TOperation; 774 StartIndex: Integer; 775 LoopVaraible: TVariable; 776 begin 777 with Compiler do begin 778 if NextCode = 'begin' then ParseProgramCode(Compiler) 779 else if NextCode = 'if' then begin 780 Expect('if'); 781 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 782 Instruction := inConditionalJump; 783 ExpressionTree := ParseExpression(Compiler); 784 Negative := True; 785 end; 786 First := Operations[Operations.Count - 1]; 787 Expect('then'); 788 ParseOperation(Compiler); 789 if NextCode = 'else' then begin 790 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 791 Instruction := inJump; 792 end; 793 Second := Operations[Operations.Count - 1]; 794 First.GotoAddress := Operations.Count; 795 Expect('else'); 796 ParseOperation(Compiler); 797 Second.GotoAddress := Operations.Count; 798 end else First.GotoAddress := Operations.Count; 799 end 800 else if NextCode = 'repeat' then begin 801 Expect('repeat'); 802 StartIndex := Operations.Count; 803 ParseOperation(Compiler); 804 Expect('until'); 805 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 806 Instruction := inConditionalJump; 807 ExpressionTree := ParseExpression(Compiler); 808 GotoAddress := StartIndex; 809 end; 810 end 811 else if NextCode = 'while' then begin 812 Expect('while'); 813 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 814 Instruction := inConditionalJump; 815 ExpressionTree := ParseExpression(Compiler); 816 end; 817 First := Operations[Operations.Count - 1]; 818 StartIndex := Operations.Count - 1; 819 Expect('do'); 820 ParseOperation(Compiler); 821 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 822 Instruction := inJump; 823 GotoAddress := StartIndex; 824 end; 825 First.GotoAddress := Operations.Count; 826 end 827 else if NextCode = 'for' then begin 828 Expect('for'); 829 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 830 Instruction := inExpressionEvaluation; 831 ExpressionTree := ParseExpression(Compiler); 832 if (ExpressionTree.NodeType <> ntOperator) and 833 (ExpressionTree.OperatorName <> ':=') then ErrorMessage('Expected assigment in for loop'); 834 if TExpression(TExpression(ExpressionTree).SubItems[0]).NodeType <> ntVariable then 835 ErrorMessage('Index in FOR loop have to be variable'); 836 LoopVaraible := TExpression(TExpression(ExpressionTree).SubItems[0]).Variable; 837 end; 838 Expect('to'); 839 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 840 Instruction := inExpressionEvaluation; 841 ExpressionTree := TExpression.Create; 842 with ExpressionTree do begin 843 NodeType := ntOperator; 844 OperatorName := '='; 845 SubItems[0] := TExpression.Create; 846 with TExpression(SubItems[0]) do begin 847 NodeType := ntVariable; 848 Variable := LoopVaraible; 849 end; 850 SubItems[1] := ParseExpression(Compiler); 851 end; 852 Negative := True; 853 end; 854 First := Operations[Operations.Count - 1]; 855 StartIndex := Operations.Count - 1; 856 Expect('do'); 857 ParseOperation(Compiler); 858 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 859 Instruction := inExpressionEvaluation; 860 ExpressionTree := TExpression.Create; 861 with ExpressionTree do begin 862 NodeType := ntOperator; 863 OperatorName := ':='; 864 SubItems[0] := TExpression.Create; 865 with TExpression(SubItems[0]) do begin 866 NodeType := ntVariable; 867 Variable := LoopVaraible; 868 end; 869 SubItems[1] := TExpression.Create; 870 with TExpression(SubItems[1]) do begin 871 NodeType := ntOperator; 872 OperatorName := '+'; 873 SubItems[0] := TExpression.Create; 874 with TExpression(SubItems[0]) do begin 875 NodeType := ntVariable; 876 Variable := LoopVaraible; 877 end; 878 SubItems[1] := TExpression.Create; 879 with TExpression(SubItems[1]) do begin 880 NodeType := ntConstant; 881 SetLength(Value, 1); 882 Value[0] := 1; 883 end; 884 end; 885 end; 886 end; 887 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 888 Instruction := inJump; 889 GotoAddress := StartIndex; 890 end; 891 First.GotoAddress := Operations.Count; 892 end 893 else begin 894 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 895 Instruction := inExpressionEvaluation; 896 ExpressionTree := ParseExpression(Compiler); 897 end; 898 end; 899 end; 900 end; 901 902 procedure TCommonBlock.ParseProgramCode(Compiler: TCompiler); 903 begin 904 with Compiler do begin 905 Expect('begin'); 906 while NextCode <> 'end' do begin 907 ParseOperation(Compiler); 908 Expect(';'); 909 end; 910 Expect('end'); 433 911 end; 434 912 end; … … 438 916 procedure TTypeList.Parse(Compiler: TCompiler); 439 917 begin 440 918 with Compiler do begin 919 Expect('type'); 920 while IsIdentificator(NextCode) do 921 with TType(Items[Add(TType.Create)]) do begin 922 Parent := Self; 923 Parse(Compiler); 924 end; 925 end; 926 end; 927 928 function TTypeList.Search(Name: string): TType; 929 var 930 I: Integer; 931 begin 932 I := 0; 933 while (I < Count) and (TType(Items[I]).Name <> Name) do Inc(I); 934 if I < Count then Result := Items[I] else begin 935 if Assigned(Parent.Parent) then Result := Parent.Parent.Types.Search(Name) 936 else begin 937 Result := nil; 938 end; 939 end; 441 940 end; 442 941 … … 444 943 445 944 procedure TVariableList.Parse(Compiler: TCompiler); 446 begin 447 448 end; 449 450 { TProgramCode } 451 452 procedure TProgramCode.Parse(Compiler: TCompiler); 453 begin 454 945 var 946 Identifiers: TStringList; 947 NewValueType: TType; 948 TypeName: string; 949 VariableName: string; 950 Variable: TVariable; 951 I: Integer; 952 begin 953 Identifiers := TStringList.Create; 954 with Compiler do begin 955 Expect('var'); 956 while IsIdentificator(NextCode) do begin 957 VariableName := ReadCode; 958 Variable := Search(VariableName); 959 if not Assigned(Variable) then begin 960 Identifiers.Add(VariableName); 961 while NextCode = ',' do begin 962 Expect(','); 963 Identifiers.Add(ReadCode); 964 end; 965 end else ErrorMessage('Pøedefinování existující promìnné.'); 966 Expect(':'); 967 TypeName := ReadCode; 968 NewValueType := Parent.Types.Search(TypeName); 969 if NewValueType = nil then ErrorMessage('Typ ' + TypeName + ' nebyl definován.') 970 else for I := 0 to Identifiers.Count - 1 do 971 with TVariable(Items[Add(TVariable.Create)]) do begin 972 Name := Identifiers[I]; 973 ValueType := NewValueType; 974 end; 975 Expect(';'); 976 end; 977 end; 978 Identifiers.Destroy; 979 end; 980 981 function TVariableList.Search(Name: string): TVariable; 982 var 983 I: Integer; 984 begin 985 I := 0; 986 while (I < Count) and (TVariable(Items[I]).Name <> Name) do Inc(I); 987 if I < Count then Result := Items[I] else begin 988 if Assigned(Parent.Parent) then Result := Parent.Parent.Variables.Search(Name) 989 else begin 990 Result := nil; 991 end; 992 end; 993 end; 994 995 { TVariable } 996 997 procedure TVariable.Parse(Compiler: TCompiler); 998 begin 999 end; 1000 1001 { TType } 1002 1003 procedure TType.Parse(Compiler: TCompiler); 1004 begin 1005 with Compiler do begin 1006 Name := NextCode; 1007 Expect('='); 1008 UsedType := Parent.Search(NextCode); 1009 end; 1010 end; 1011 1012 { TMethodList } 1013 1014 procedure TMethodList.Parse(Compiler: TCompiler); 1015 begin 1016 1017 end; 1018 1019 function TMethodList.Search(Name: string): TMethod; 1020 var 1021 I: Integer; 1022 begin 1023 I := 0; 1024 while (I < Count) and (TMethod(Items[I]).Name <> Name) do Inc(I); 1025 if I < Count then Result := Items[I] else begin 1026 if Assigned(Parent.Parent) then Result := Parent.Parent.Methods.Search(Name) 1027 else begin 1028 Result := nil; 1029 end; 1030 end; 1031 end; 1032 1033 { TExpression } 1034 1035 constructor TExpression.Create; 1036 begin 1037 SubItems := TList.Create; 1038 SubItems.Count := 2; 1039 end; 1040 1041 destructor TExpression.Destroy; 1042 begin 1043 SubItems.Destroy; 1044 inherited; 1045 end; 1046 1047 procedure TExpression.GenerateAssembler(Compiler: TCompiler; 1048 LabelPrefix: string); 1049 var 1050 I: Integer; 1051 begin 1052 with Compiler do 1053 case NodeType of 1054 ntNone: ; 1055 ntVariable: AddInstruction('', 'CALL', '', ''); 1056 ntMethod: AddInstruction('', 'CALL', '', ''); 1057 ntConstant: AddInstruction('', 'CONST', '', ''); 1058 ntOperator: begin 1059 for I := 0 to SubItems.Count - 1 do 1060 TExpression(SubItems[I]).GenerateAssembler(Compiler, LabelPrefix); 1061 if OperatorName = '+' then AddInstruction('', 'ADD', '', '') 1062 else if OperatorName = '-' then AddInstruction('', 'SUB', '', '') 1063 else if OperatorName = '*' then AddInstruction('', 'MUL', '', '') 1064 else if OperatorName = '/' then AddInstruction('', 'DIV', '', '') 1065 else if OperatorName = 'div' then AddInstruction('', 'DIV', '', '') 1066 else if OperatorName = 'mod' then AddInstruction('', 'MOD', '', '') 1067 else if OperatorName = 'xor' then AddInstruction('', 'XOR', '', '') 1068 else if OperatorName = 'or' then AddInstruction('', 'OR', '', '') 1069 else if OperatorName = 'and' then AddInstruction('', 'AND', '', '') 1070 else if OperatorName = 'not' then AddInstruction('', 'NEG', '', '') 1071 else if OperatorName = ':=' then AddInstruction('', 'ST', '', '') 1072 else if OperatorName = '>' then AddInstruction('', 'CP', '', '') 1073 else if OperatorName = '>=' then AddInstruction('', 'CP', '', '') 1074 else if OperatorName = '<' then AddInstruction('', 'CP', '', '') 1075 else if OperatorName = '<=' then AddInstruction('', 'CP', '', '') 1076 else if OperatorName = '=' then AddInstruction('', 'TST', '', '') 1077 else if OperatorName = '<>' then AddInstruction('', 'CP', '', ''); 1078 end; 1079 end; 1080 end; 1081 1082 { TAssemblerLine } 1083 1084 function TAssemblerLine.AsString: string; 1085 begin 1086 Result := LabelName + ': ' + Instruction + ' ' + Operand1 + ',' + Operand2; 455 1087 end; 456 1088
Note:
See TracChangeset
for help on using the changeset viewer.