Changeset 222


Ignore:
Timestamp:
Nov 25, 2020, 12:18:45 AM (3 years ago)
Author:
chronos
Message:
  • Added: Support for more expression operators.
  • Added: Support for brackets in expressions.
Location:
branches/interpreter2
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter2/Forms/UFormMain.lfm

    r221 r222  
    4848  end
    4949  object MainMenu1: TMainMenu
    50     Left = 790
    51     Top = 753
     50    Left = 760
     51    Top = 760
    5252    object MenuItemFile: TMenuItem
    5353      Caption = 'File'
     
    9999      Caption = 'Run'
    100100      OnExecute = ARunExecute
     101      ShortCut = 120
    101102    end
    102103    object ACompile: TAction
    103104      Caption = 'Compile'
    104105      OnExecute = ACompileExecute
     106      ShortCut = 16497
    105107    end
    106108    object AExit: TAction
  • branches/interpreter2/Forms/UFormMain.pas

    r221 r222  
    77uses
    88  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Menus,
    9   ActnList, ExtCtrls, SynHighlighterPas, SynEdit, USource, UOptimizer;
     9  ActnList, ExtCtrls, SynHighlighterPas, SynEdit, USource, UOptimizer,
     10  UGenerator;
    1011
    1112type
     
    5253    Prog: TProgram;
    5354    Initialized: Boolean;
     55    procedure Generate(GeneratorClass: TGeneratorClass);
    5456    procedure ExecutorOutput(Text: string);
    5557    procedure InterpreterError(Pos: TPoint; Text: string);
     
    9092procedure TFormMain.FormDestroy(Sender: TObject);
    9193begin
    92   if Assigned(Prog) then Prog.Free;
     94  if Assigned(Prog) then FreeAndNil(Prog);
    9395end;
    9496
     
    99101  DockForm(FormOutput, PanelOutput);
    100102  UpdateInterface;
     103end;
     104
     105procedure TFormMain.Generate(GeneratorClass: TGeneratorClass);
     106var
     107  Generator: TGenerator;
     108  TargetFileName: string;
     109begin
     110  Generator := GeneratorClass.Create;
     111  try
     112    Generator.Prog := Prog;
     113    Generator.Generate;
     114    FormOutput.SetText(Generator.Output);
     115    TargetFileName := 'Generated' + DirectorySeparator +
     116      Generator.Name + DirectorySeparator + 'Test' + Generator.FileExt;
     117    ForceDirectories(ExtractFileDir(TargetFileName));
     118    FormOutput.SynEditOutput.Lines.SaveToFile(TargetFileName);
     119  finally
     120    Generator.Free;
     121  end;
    101122end;
    102123
     
    122143
    123144procedure TFormMain.AGenerateCSharpExecute(Sender: TObject);
    124 var
    125   Generator: TGeneratorCSharp;
    126145begin
    127146  ACompile.Execute;
     
    130149  FormOutput.Clear;
    131150  if Assigned(Prog) then begin
    132     Generator := TGeneratorCSharp.Create;
    133     Generator.Prog := Prog;
    134     Generator.Generate;
    135     FormOutput.SetText(Generator.Output);
    136     Generator.Free;
    137     FormOutput.SynEditOutput.Lines.SaveToFile('Generated' + DirectorySeparator + 'Test.cs');
     151    Generate(TGeneratorCSharp);
    138152  end;
    139153end;
    140154
    141155procedure TFormMain.AGeneratePascalExecute(Sender: TObject);
    142 var
    143   Generator: TGeneratorPascal;
    144156begin
    145157  ACompile.Execute;
     
    147159  FormOutput.SynEditOutput.Lines.Clear;
    148160  if Assigned(Prog) then begin
    149     Generator := TGeneratorPascal.Create;
    150     Generator.Prog := Prog;
    151     Generator.Generate;
    152     FormOutput.SynEditOutput.Lines.Text := Generator.Output;
    153     Generator.Free;
    154     FormOutput.SynEditOutput.Lines.SaveToFile('Generated' + DirectorySeparator + 'Test.pas');
     161    Generate(TGeneratorPascal);
    155162  end;
    156163end;
    157164
    158165procedure TFormMain.AGeneratePhpExecute(Sender: TObject);
    159 var
    160   Generator: TGeneratorPhp;
    161166begin
    162167  ACompile.Execute;
     
    165170  FormOutput.SynEditOutput.Lines.Clear;
    166171  if Assigned(Prog) then begin
    167     Generator := TGeneratorPhp.Create;
    168     Generator.Prog := Prog;
    169     Generator.Generate;
    170     FormOutput.SynEditOutput.Lines.Text := Generator.Output;
    171     Generator.Free;
    172     FormOutput.SynEditOutput.Lines.SaveToFile('Generated' + DirectorySeparator + 'Test.php');
     172    Generate(TGeneratorPhp);
    173173  end;
    174174end;
    175175
    176176procedure TFormMain.AGenerateXmlExecute(Sender: TObject);
    177 var
    178   Generator: TGeneratorXml;
    179177begin
    180178  ACompile.Execute;
     
    182180  FormOutput.SynEditOutput.Lines.Clear;
    183181  if Assigned(Prog) then begin
    184     Generator := TGeneratorXml.Create;
    185     Generator.Prog := Prog;
    186     Generator.Generate;
    187     FormOutput.SynEditOutput.Lines.Text := Generator.Output;
    188     Generator.Free;
    189     FormOutput.SynEditOutput.Lines.SaveToFile('Generated' + DirectorySeparator + 'Test.xml');
     182    Generate(TGeneratorXml);
    190183  end;
    191184end;
  • branches/interpreter2/Generators/UGeneratorCSharp.pas

    r221 r222  
    3131    procedure GenerateExpressionOperation(Block: TBlock; Expression: TExpressionOperation);
    3232    procedure GenerateExpressionOperand(Block: TBlock; Expression: TExpressionOperand);
     33    procedure GenerateExpressionBrackets(Block: TBlock; Expression: TExpressionBrackets);
    3334    procedure GenerateBreak(Block: TBlock; BreakCmd: TBreak);
    3435    procedure GenerateContinue(Block: TBlock; ContinueCmd: TContinue);
     
    3738    procedure GenerateValue(Value: TValue);
    3839  public
    39     Prog: TProgram;
    4040    procedure Generate; override;
    41   end;
     41    constructor Create; override;
     42  end;
     43
    4244
    4345implementation
     46
     47const
     48  ExpressionOperatorTextCSharp: array[TExpressionOperator] of string = ('', '+',
     49    '-', '*', '/', '/', '%', '&', '^', '|', '<<',
     50    '>>', '==', '!=', '<', '>', '<=','>=', '!');
    4451
    4552{ TGeneratorCSharp }
     
    144151  if Expression is TExpressionOperand then
    145152    GenerateExpressionOperand(Block, TExpressionOperand(Expression))
     153  else
     154  if Expression is TExpressionBrackets then
     155    GenerateExpressionBrackets(Block, TExpressionBrackets(Expression))
    146156  else raise Exception.Create('Unknown expression class.');
    147157end;
     
    154164  for I := 0 to Expression.Items.Count - 1 do begin
    155165    if I > 0 then begin
    156       if Expression.Operation = eoAdd then AddText(' + ')
    157       else if Expression.Operation = eoSub then AddText(' - ')
    158       else if Expression.Operation = eoEqual then AddText(' == ')
    159       else if Expression.Operation = eoNotEqual then AddText(' != ');
     166      AddText(' ' + ExpressionOperatorTextCSharp[Expression.Operation] + ' ');
    160167    end;
    161168    GenerateExpression(Block, TExpression(Expression.Items[I]));
     
    173180    else raise Exception.Create('Unsupported exception operand type.');
    174181  end;
     182end;
     183
     184procedure TGeneratorCSharp.GenerateExpressionBrackets(Block: TBlock;
     185  Expression: TExpressionBrackets);
     186begin
     187  AddText('(');
     188  GenerateExpression(Block, Expression.Expression);
     189  AddText(')');
    175190end;
    176191
     
    233248
    234249procedure TGeneratorCSharp.GenerateBlock(ParentBlock: TBlock; Block: TBlock);
    235 var
    236   I: Integer;
    237250begin
    238251  if Block.BeginEnd.Commands.Count > 0 then begin
     
    353366end;
    354367
     368constructor TGeneratorCSharp.Create;
     369begin
     370  inherited;
     371  Name := 'CSharp';
     372  FileExt := '.cs';
     373end;
     374
    355375end.
    356376
  • branches/interpreter2/Generators/UGeneratorPascal.pas

    r221 r222  
    3131    procedure GenerateExpressionOperation(Block: TBlock; Expression: TExpressionOperation);
    3232    procedure GenerateExpressionOperand(Block: TBlock; Expression: TExpressionOperand);
     33    procedure GenerateExpressionBrackets(Block: TBlock; Expression: TExpressionBrackets);
    3334    procedure GenerateBreak(Block: TBlock; BreakCmd: TBreak);
    3435    procedure GenerateContinue(Block: TBlock; ContinueCmd: TContinue);
    3536    procedure GenerateValue(Value: TValue);
    3637  public
    37     Prog: TProgram;
    3838    procedure Generate; override;
     39    constructor Create; override;
    3940  end;
    4041
     
    134135  if Expression is TExpressionOperand then
    135136    GenerateExpressionOperand(Block, TExpressionOperand(Expression))
     137  else
     138  if Expression is TExpressionBrackets then
     139    GenerateExpressionBrackets(Block, TExpressionBrackets(Expression))
    136140  else raise Exception.Create('Unknown expression class.');
    137141end;
     
    145149    if I > 0 then begin
    146150      AddText(' ');
    147       if Expression.Operation = eoAdd then AddText('+')
    148       else if Expression.Operation = eoSub then AddText('-')
    149       else if Expression.Operation = eoEqual then AddText('=')
    150       else if Expression.Operation = eoNotEqual then AddText('<>');
     151      AddText(ExpressionOperatorText[Expression.Operation]);
    151152      AddText(' ');
    152153    end;
     
    165166    else raise Exception.Create('Unsupported exception operand type.');
    166167  end;
     168end;
     169
     170procedure TGeneratorPascal.GenerateExpressionBrackets(Block: TBlock;
     171  Expression: TExpressionBrackets);
     172begin
     173  AddText('(');
     174  GenerateExpression(Block, Expression.Expression);
     175  AddText(')');
    167176end;
    168177
     
    313322end;
    314323
     324constructor TGeneratorPascal.Create;
     325begin
     326  inherited;
     327  Name := 'Pascal';
     328  FileExt := '.pas';
     329end;
     330
    315331end.
    316332
  • branches/interpreter2/Generators/UGeneratorPhp.pas

    r221 r222  
    3030    procedure GenerateExpressionOperation(Block: TBlock; Expression: TExpressionOperation);
    3131    procedure GenerateExpressionOperand(Block: TBlock; Expression: TExpressionOperand);
     32    procedure GenerateExpressionBrackets(Block: TBlock; Expression: TExpressionBrackets);
    3233    procedure GenerateBreak(Block: TBlock; BreakCmd: TBreak);
    3334    procedure GenerateReturn(Block: TBlock; Return: TReturn);
     
    3536    procedure GenerateValue(Value: TValue);
    3637  public
    37     Prog: TProgram;
    3838    procedure Generate; override;
    39   end;
     39    constructor Create; override;
     40  end;
     41
    4042
    4143implementation
     44
     45const
     46  ExpressionOperatorTextPhp: array[TExpressionOperator] of string = ('', '+',
     47    '-', '*', '/', '/', '%', 'and', 'xor', 'or', '<<',
     48    '>>', '==', '!=', '<', '>', '<=','>=', '!');
    4249
    4350{ TGeneratorPhp }
     
    142149  if Expression is TExpressionOperand then
    143150    GenerateExpressionOperand(Block, TExpressionOperand(Expression))
     151  else
     152  if Expression is TExpressionBrackets then
     153    GenerateExpressionBrackets(Block, TExpressionBrackets(Expression))
    144154  else raise Exception.Create('Unknown expression class.');
    145155end;
     
    156166        else AddText(' + ');
    157167      end
    158       else if Expression.Operation = eoSub then AddText(' - ')
    159       else if Expression.Operation = eoEqual then AddText(' == ')
    160       else if Expression.Operation = eoNotEqual then AddText(' != ');
     168      else AddText(' ' + ExpressionOperatorTextPhp[Expression.Operation] + ' ');
    161169    end;
    162170    GenerateExpression(Block, TExpression(Expression.Items[I]));
     
    174182    else raise Exception.Create('Unsupported exception operand type.');
    175183  end;
     184end;
     185
     186procedure TGeneratorPhp.GenerateExpressionBrackets(Block: TBlock;
     187  Expression: TExpressionBrackets);
     188begin
     189  AddText('(');
     190  GenerateExpression(Block, Expression.Expression);
     191  AddText(')');
    176192end;
    177193
     
    290306end;
    291307
     308constructor TGeneratorPhp.Create;
     309begin
     310  inherited;
     311  Name := 'PHP';
     312  FileExt := '.php';
     313end;
     314
    292315end.
    293316
  • branches/interpreter2/Generators/UGeneratorXml.pas

    r221 r222  
    1616    procedure GenerateNode(SourceNode: TSourceNode);
    1717  public
    18     Prog: TProgram;
    1918    procedure Generate; override;
     19    constructor Create; override;
    2020  end;
    2121
     
    7373end;
    7474
     75constructor TGeneratorXml.Create;
     76begin
     77  inherited;
     78  Name := 'XML';
     79  FileExt := '.xml';
     80end;
     81
    7582end.
    7683
  • branches/interpreter2/Parsers/UParserPascal.pas

    r221 r222  
    99
    1010type
     11
     12  { TParserPascal }
     13
    1114  TParserPascal = class(TParser)
    1215  protected
     
    2124    function ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter): Boolean;
    2225    function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean;
    23     function ParseExpression(Block: TBlock; out Expression: TExpression): Boolean;
     26    function ParseExpression(Block: TBlock; out Expression: TExpression;
     27      WithOperation: Boolean = True): Boolean;
    2428    function ParseExpressionOperation(Block: TBlock; out ExpressionOperation: TExpressionOperation): Boolean;
    2529    function ParseExpressionOperand(Block: TBlock; out ExpressionOperand: TExpressionOperand): Boolean;
     30    function ParseExpressionBrackets(Block: TBlock; out ExpressionBrackets: TExpressionBrackets): Boolean;
    2631    function ParseConstantRef(Block: TBlock; out ConstantRef: TConstant): Boolean;
    2732    function ParseConstant(Block: TBlock; out ConstantRef: TConstant): Boolean;
     
    4247  Command: TCommand;
    4348begin
    44   if Tokenizer.CheckNext('begin', tkKeyword) then begin
    45     Tokenizer.Expect('begin', tkKeyword);
     49  if Tokenizer.CheckNextAndRead('begin', tkKeyword) then begin
    4650    BeginEnd := TBeginEnd.Create;
    4751    Result := True;
     
    7781      FunctionCall := TFunctionCall.Create;
    7882      FunctionCall.FunctionDef := FunctionDef;
    79       if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin
    80         Tokenizer.Expect('(', tkSpecialSymbol);
     83      if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin
    8184        for I := 0 to FunctionDef.Params.Count - 1 do begin
    8285          if I > 0 then Tokenizer.Expect(',', tkSpecialSymbol);
     
    160163  Prog.SystemBlock.Free;
    161164  Prog.SystemBlock := SystemBlock;
    162   if Tokenizer.CheckNext('program', tkKeyword) then begin
    163     Tokenizer.Expect('program', tkKeyword);
     165  if Tokenizer.CheckNextAndRead('program', tkKeyword) then begin
    164166    Token := Tokenizer.GetNext;
    165167    if Token.Kind = tkIdentifier then
     
    216218  TypeRef: TType;
    217219begin
    218   if Tokenizer.CheckNext('var', tkKeyword) then begin
    219     Result := True;
    220     Tokenizer.Expect('var', tkKeyword);
     220  if Tokenizer.CheckNextAndRead('var', tkKeyword) then begin
     221    Result := True;
    221222    while Tokenizer.CheckNextKind(tkIdentifier) do begin
    222223      Token := Tokenizer.GetNext;
     
    251252  TypeRef: TType;
    252253begin
    253   if Tokenizer.CheckNext('const', tkKeyword) then begin
    254     Result := True;
    255     Tokenizer.Expect('const', tkKeyword);
     254  if Tokenizer.CheckNextAndRead('const', tkKeyword) then begin
     255    Result := True;
    256256    while Tokenizer.CheckNextKind(tkIdentifier) do begin
    257257      Token := Tokenizer.GetNext;
     
    300300begin
    301301  Result := False;
    302   if Tokenizer.CheckNext('function', tkKeyword) then begin
    303     Tokenizer.Expect('function', tkKeyword);
     302  if Tokenizer.CheckNextAndRead('function', tkKeyword) then begin
    304303    Result := True;
    305304    Func := TFunction.Create;
     
    307306    if Token.Kind = tkIdentifier then begin
    308307      Func.Name := Token.Text;
    309       if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin
    310         Tokenizer.Expect('(', tkSpecialSymbol);
     308      if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin
    311309        while not Tokenizer.CheckNext(')', tkSpecialSymbol) do begin
    312310          if Func.Params.Count > 0 then Tokenizer.Expect(',', tkSpecialSymbol);
     
    324322        end;
    325323      end;
    326       if Tokenizer.CheckNext(':', tkSpecialSymbol) then begin
    327         Tokenizer.Expect(':', tkSpecialSymbol);
     324      if Tokenizer.CheckNextAndRead(':', tkSpecialSymbol) then begin
    328325        Token := Tokenizer.GetNext;
    329326        if Token.Kind = tkIdentifier then begin
     
    402399end;
    403400
    404 function TParserPascal.ParseExpression(Block: TBlock; out Expression: TExpression
    405   ): Boolean;
     401function TParserPascal.ParseExpression(Block: TBlock; out Expression: TExpression;
     402  WithOperation: Boolean = True): Boolean;
    406403var
    407404  ExpressionOperation: TExpressionOperation;
    408405  ExpressionOperand: TExpressionOperand;
    409 begin
    410   Result := False;
    411   if ParseExpressionOperation(Block, ExpressionOperation) then begin
     406  ExpressionBrackets: TExpressionBrackets;
     407begin
     408  Result := False;
     409  if WithOperation and ParseExpressionOperation(Block, ExpressionOperation) then begin
    412410    Result := True;
    413411    Expression := ExpressionOperation;
     412  end else
     413  if ParseExpressionBrackets(Block, ExpressionBrackets) then begin
     414    Result := True;
     415    Expression := ExpressionBrackets;
    414416  end else
    415417  if ParseExpressionOperand(Block, ExpressionOperand) then begin
     
    422424  ExpressionOperation: TExpressionOperation): Boolean;
    423425var
    424   Operand: TExpressionOperand;
    425   Token: TToken;
    426426  Expression: TExpression;
     427  Token: TToken;
    427428  LastPos: TTokenizerPos;
    428429  I: Integer;
     
    431432  Result := False;
    432433  LastPos := Tokenizer.Pos;
    433   if ParseExpressionOperand(Block, Operand) then begin
     434  if ParseExpression(Block, Expression, False) then begin
    434435    Token := Tokenizer.GetNext;
    435     if (Token.Kind = tkSpecialSymbol) and Tokenizer.IsOperator(Token.Text) then begin
     436    if Tokenizer.IsOperator(Token.Text) then begin
    436437      Result := True;
    437438      ExpressionOperation := TExpressionOperation.Create;
    438       ExpressionOperation.TypeRef := Operand.GetType;
    439       if Token.Text = '+' then ExpressionOperation.Operation := eoAdd
    440       else if Token.Text = '-' then ExpressionOperation.Operation := eoSub
    441       else if Token.Text = '=' then ExpressionOperation.Operation := eoEqual
    442       else if Token.Text = '<>' then ExpressionOperation.Operation := eoNotEqual
    443       else Error('Unsupported operator ' + Token.Text);
     439      ExpressionOperation.Items.Add(Expression);
     440      ExpressionOperation.TypeRef := Expression.GetType;
     441      ExpressionOperation.Operation := GetOperatorByName(Token.Text);
     442      if ExpressionOperation.Operation = eoNone then
     443        Error('Unsupported operator ' + Token.Text);
    444444      ExpressionOperation.FunctionRef := ExpressionOperation.TypeRef.Functions.SearchByName(ExpressionOperation.GetFunctionName);
    445       if not Assigned(ExpressionOperation.FunctionRef.ResultType) then
    446         raise Exception.Create('Missing result type for function');
    447       ExpressionOperation.TypeRef := ExpressionOperation.FunctionRef.ResultType;
    448       ExpressionOperation.Items.Add(Operand);
    449       I := 1;
    450       if ParseExpression(Block, Expression) then begin
    451         ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef;
    452         if Expression.GetType = ExpectedType then
    453           ExpressionOperation.Items.Add(Expression)
    454           else Error('Expression operands needs to be same type. Expected ' + ExpectedType.Name + ' but found ' + Expression.GetType.Name);
    455       end else Error('Missing operand.');
    456     end else Operand.Free;
     445      if Assigned(ExpressionOperation.FunctionRef) then begin
     446        if not Assigned(ExpressionOperation.FunctionRef.ResultType) then
     447          raise Exception.Create('Missing result type for function');
     448        ExpressionOperation.TypeRef := ExpressionOperation.FunctionRef.ResultType;
     449        I := 1;
     450        if ParseExpression(Block, Expression) then begin
     451          ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef;
     452          if Expression.GetType = ExpectedType then
     453            ExpressionOperation.Items.Add(Expression)
     454            else Error('Expression operands needs to be same type. Expected ' + ExpectedType.Name + ' but found ' + Expression.GetType.Name);
     455        end else Error('Missing operand.');
     456      end else Error('Operator ' + Token.Text + ' not defind for type ' + ExpressionOperation.TypeRef.Name + '.');
     457    end else Expression.Free;
    457458  end;
    458459  if not Result then Tokenizer.Pos := LastPos;
     
    490491    ExpressionOperand.VariableRef := Variable;
    491492    ExpressionOperand.OperandType := otVariableRef;
    492   end else Error('Expected expression operand.');
     493  end else
     494    Error('Expected expression operand.');
     495end;
     496
     497function TParserPascal.ParseExpressionBrackets(Block: TBlock; out
     498  ExpressionBrackets: TExpressionBrackets): Boolean;
     499var
     500  Expression: TExpression;
     501begin
     502  Result := False;
     503  if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin
     504    Result := True;
     505    if ParseExpression(Block, Expression) then begin
     506      ExpressionBrackets := TExpressionBrackets.Create;
     507      ExpressionBrackets.Expression := Expression;
     508    end;
     509    Tokenizer.Expect(')', tkSpecialSymbol);
     510  end;
    493511end;
    494512
     
    562580begin
    563581  Result := False;
    564   if Tokenizer.CheckNext('if', tkKeyword) then begin
    565     Tokenizer.Expect('if', tkKeyword);
     582  if Tokenizer.CheckNextAndRead('if', tkKeyword) then begin
    566583    Result := True;
    567584    IfThenElse := TIfThenElse.Create;
     
    574591        IfThenElse.CommandThen := Command;
    575592        Command.Parent := IfThenElse;
    576         if Tokenizer.CheckNext('else', tkKeyword) then begin
    577           Tokenizer.Expect('else', tkKeyword);
     593        if Tokenizer.CheckNextAndRead('else', tkKeyword) then begin
    578594          if ParseCommand(Block, Command) then begin
    579595            IfThenElse.CommandElse.Free;
     
    593609begin
    594610  Result := False;
    595   if Tokenizer.CheckNext('while', tkKeyword) then begin
    596     Tokenizer.Expect('while', tkKeyword);
     611  if Tokenizer.CheckNextAndRead('while', tkKeyword) then begin
    597612    Result := True;
    598613    WhileDo := TWhileDo.Create;
     
    617632begin
    618633  Result := False;
    619   if Tokenizer.CheckNext('repeat', tkKeyword) then begin
    620     Tokenizer.Expect('repeat', tkKeyword);
     634  if Tokenizer.CheckNextAndRead('repeat', tkKeyword) then begin
    621635    RepeatUntil := TRepeatUntil.Create;
    622636    Result := True;
     
    647661begin
    648662  Result := False;
    649   if Tokenizer.CheckNext('for', tkKeyword) then begin
    650     Tokenizer.Expect('for', tkKeyword);
     663  if Tokenizer.CheckNextAndRead('for', tkKeyword) then begin
    651664    Result := True;
    652665    ForToDo := TForToDo.Create;
     
    676689begin
    677690  Result := False;
    678   if Tokenizer.CheckNext('break', tkKeyword) then begin
    679     Tokenizer.Expect('break', tkKeyword);
     691  if Tokenizer.CheckNextAndRead('break', tkKeyword) then begin
    680692    Result := True;
    681693    BreakCmd := TBreak.Create;
     
    687699begin
    688700  Result := False;
    689   if Tokenizer.CheckNext('continue', tkKeyword) then begin
    690     Tokenizer.Expect('continue', tkKeyword);
     701  if Tokenizer.CheckNextAndRead('continue', tkKeyword) then begin
    691702    Result := True;
    692703    ContinueCmd := TContinue.Create;
  • branches/interpreter2/Test.pas

    r214 r222  
    1515
    1616begin 
     17  WriteLn('10 * 3 = ' + IntToStr((1 + 2) * (3 + 4)));
     18
    1719  X := 'A' + 'B';
    1820  WriteLn(X);
     
    2022  B := IntToStr(C);
    2123  A := B;
    22  
     24
    2325  // If-Then-Else
    2426  if A = '2' then begin
  • branches/interpreter2/UExecutor.pas

    r221 r222  
    9292    function ExecuteStrToInt(Params: array of TValue): TValue;
    9393    function ExecuteBooleanAssign(Params: array of TValue): TValue;
     94    function ExecuteBooleanNot(Params: array of TValue): TValue;
    9495    function ExecuteBooleanEqual(Params: array of TValue): TValue;
    9596    function ExecuteBooleanNotEqual(Params: array of TValue): TValue;
     
    101102    function ExecuteIntegerAdd(Params: array of TValue): TValue;
    102103    function ExecuteIntegerSub(Params: array of TValue): TValue;
     104    function ExecuteIntegerMul(Params: array of TValue): TValue;
     105    function ExecuteIntegerIntDiv(Params: array of TValue): TValue;
     106    function ExecuteIntegerMod(Params: array of TValue): TValue;
    103107    function ExecuteIntegerEqual(Params: array of TValue): TValue;
    104108    function ExecuteIntegerNotEqual(Params: array of TValue): TValue;
     109    function ExecuteIntegerLesser(Params: array of TValue): TValue;
     110    function ExecuteIntegerHigher(Params: array of TValue): TValue;
     111    function ExecuteIntegerLesserOrEqual(Params: array of TValue): TValue;
     112    function ExecuteIntegerHigherOrEqual(Params: array of TValue): TValue;
     113    function ExecuteIntegerAnd(Params: array of TValue): TValue;
     114    function ExecuteIntegerOr(Params: array of TValue): TValue;
     115    function ExecuteIntegerXor(Params: array of TValue): TValue;
     116    function ExecuteIntegerShr(Params: array of TValue): TValue;
     117    function ExecuteIntegerShl(Params: array of TValue): TValue;
    105118    procedure InitExecutorBlock(ExecutorBlock: TExecutorBlock; Block: TBlock);
    106119  public
     
    121134    function ExecuteExpressionOperation(Block: TExecutorBlock; Expression: TExpressionOperation): TValue;
    122135    function ExecuteExpressionOperand(Block: TExecutorBlock; Expression: TExpressionOperand): TValue;
     136    function ExecuteExpressionBrackets(Block: TExecutorBlock; Expression: TExpressionBrackets): TValue;
    123137    procedure Run;
    124138    procedure Output(Text: string);
     
    323337end;
    324338
     339function TExecutor.ExecuteBooleanNot(Params: array of TValue): TValue;
     340begin
     341  Result := TValueBoolean.Create;
     342  TValueBoolean(Result).Value := not TValueBoolean(Params[0]).Value;
     343end;
     344
    325345function TExecutor.ExecuteBooleanEqual(Params: array of TValue): TValue;
    326346begin
     
    377397end;
    378398
     399function TExecutor.ExecuteIntegerMul(Params: array of TValue): TValue;
     400begin
     401  Result := TValueInteger.Create;
     402  TValueInteger(Result).Value := TValueInteger(Params[0]).Value * TValueInteger(Params[1]).Value;
     403end;
     404
     405function TExecutor.ExecuteIntegerIntDiv(Params: array of TValue): TValue;
     406begin
     407  Result := TValueInteger.Create;
     408  TValueInteger(Result).Value := TValueInteger(Params[0]).Value div TValueInteger(Params[1]).Value;
     409end;
     410
     411function TExecutor.ExecuteIntegerMod(Params: array of TValue): TValue;
     412begin
     413  Result := TValueInteger.Create;
     414  TValueInteger(Result).Value := TValueInteger(Params[0]).Value mod TValueInteger(Params[1]).Value;
     415end;
     416
    379417function TExecutor.ExecuteIntegerEqual(Params: array of TValue): TValue;
    380418begin
     
    387425  Result := TValueBoolean.Create;
    388426  TValueBoolean(Result).Value := TValueInteger(Params[0]).Value <> TValueInteger(Params[1]).Value;
     427end;
     428
     429function TExecutor.ExecuteIntegerLesser(Params: array of TValue): TValue;
     430begin
     431  Result := TValueBoolean.Create;
     432  TValueBoolean(Result).Value := TValueInteger(Params[0]).Value < TValueInteger(Params[1]).Value;
     433end;
     434
     435function TExecutor.ExecuteIntegerHigher(Params: array of TValue): TValue;
     436begin
     437  Result := TValueBoolean.Create;
     438  TValueBoolean(Result).Value := TValueInteger(Params[0]).Value > TValueInteger(Params[1]).Value;
     439end;
     440
     441function TExecutor.ExecuteIntegerLesserOrEqual(Params: array of TValue): TValue;
     442begin
     443  Result := TValueBoolean.Create;
     444  TValueBoolean(Result).Value := TValueInteger(Params[0]).Value <= TValueInteger(Params[1]).Value;
     445end;
     446
     447function TExecutor.ExecuteIntegerHigherOrEqual(Params: array of TValue): TValue;
     448begin
     449  Result := TValueBoolean.Create;
     450  TValueBoolean(Result).Value := TValueInteger(Params[0]).Value >= TValueInteger(Params[1]).Value;
     451end;
     452
     453function TExecutor.ExecuteIntegerAnd(Params: array of TValue): TValue;
     454begin
     455  Result := TValueInteger.Create;
     456  TValueInteger(Result).Value := TValueInteger(Params[0]).Value and TValueInteger(Params[1]).Value;
     457end;
     458
     459function TExecutor.ExecuteIntegerOr(Params: array of TValue): TValue;
     460begin
     461  Result := TValueInteger.Create;
     462  TValueInteger(Result).Value := TValueInteger(Params[0]).Value or TValueInteger(Params[1]).Value;
     463end;
     464
     465function TExecutor.ExecuteIntegerXor(Params: array of TValue): TValue;
     466begin
     467  Result := TValueInteger.Create;
     468  TValueInteger(Result).Value := TValueInteger(Params[0]).Value xor TValueInteger(Params[1]).Value;
     469end;
     470
     471function TExecutor.ExecuteIntegerShr(Params: array of TValue): TValue;
     472begin
     473  Result := TValueInteger.Create;
     474  TValueInteger(Result).Value := TValueInteger(Params[0]).Value shr TValueInteger(Params[1]).Value;
     475end;
     476
     477function TExecutor.ExecuteIntegerShl(Params: array of TValue): TValue;
     478begin
     479  Result := TValueInteger.Create;
     480  TValueInteger(Result).Value := TValueInteger(Params[0]).Value shl TValueInteger(Params[1]).Value;
    389481end;
    390482
     
    410502          ExecutorFunction.Callback := ExecuteBooleanNotEqual;
    411503        end;
     504        if ExecutorFunction.FunctionDef.Name = '_Not' then begin
     505          ExecutorFunction.Callback := ExecuteBooleanNot;
     506        end else
    412507      end else
    413508      if ExecutorType.TypeRef.Name = 'string' then begin
     
    435530          ExecutorFunction.Callback := ExecuteIntegerSub;
    436531        end else
     532        if ExecutorFunction.FunctionDef.Name = '_Mul' then begin
     533          ExecutorFunction.Callback := ExecuteIntegerMul;
     534        end else
     535        if ExecutorFunction.FunctionDef.Name = '_IntDiv' then begin
     536          ExecutorFunction.Callback := ExecuteIntegerIntDiv;
     537        end else
     538        if ExecutorFunction.FunctionDef.Name = '_IntMod' then begin
     539          ExecutorFunction.Callback := ExecuteIntegerMod;
     540        end else
    437541        if ExecutorFunction.FunctionDef.Name = '_Equal' then begin
    438542          ExecutorFunction.Callback := ExecuteIntegerEqual;
     
    440544        if ExecutorFunction.FunctionDef.Name = '_NotEqual' then begin
    441545          ExecutorFunction.Callback := ExecuteIntegerNotEqual;
     546        end;
     547        if ExecutorFunction.FunctionDef.Name = '_Lesser' then begin
     548          ExecutorFunction.Callback := ExecuteIntegerLesser;
     549        end else
     550        if ExecutorFunction.FunctionDef.Name = '_Higher' then begin
     551          ExecutorFunction.Callback := ExecuteIntegerHigher;
     552        end;
     553        if ExecutorFunction.FunctionDef.Name = '_LesserOrEqual' then begin
     554          ExecutorFunction.Callback := ExecuteIntegerLesserOrEqual;
     555        end else
     556        if ExecutorFunction.FunctionDef.Name = '_HigherOrEqual' then begin
     557          ExecutorFunction.Callback := ExecuteIntegerHigherOrEqual;
     558        end;
     559        if ExecutorFunction.FunctionDef.Name = '_And' then begin
     560          ExecutorFunction.Callback := ExecuteIntegerAnd;
     561        end;
     562        if ExecutorFunction.FunctionDef.Name = '_Or' then begin
     563          ExecutorFunction.Callback := ExecuteIntegerOr;
     564        end;
     565        if ExecutorFunction.FunctionDef.Name = '_Xor' then begin
     566          ExecutorFunction.Callback := ExecuteIntegerXor;
     567        end;
     568        if ExecutorFunction.FunctionDef.Name = '_Shr' then begin
     569          ExecutorFunction.Callback := ExecuteIntegerShr;
     570        end;
     571        if ExecutorFunction.FunctionDef.Name = '_Shl' then begin
     572          ExecutorFunction.Callback := ExecuteIntegerShl;
    442573        end;
    443574      end;
     
    692823  if Expression is TExpressionOperand then
    693824    Result := ExecuteExpressionOperand(Block, TExpressionOperand(Expression))
    694   else raise Exception.Create('Unknown expression class.');
     825  else
     826  if Expression is TExpressionBrackets then
     827    Result := ExecuteExpressionBrackets(Block, TExpressionBrackets(Expression))
     828  else
     829  raise Exception.Create('Unknown expression class.');
    695830end;
    696831
     
    733868end;
    734869
     870function TExecutor.ExecuteExpressionBrackets(Block: TExecutorBlock;
     871  Expression: TExpressionBrackets): TValue;
     872begin
     873  Result := ExecuteExpression(Block, Expression.Expression);
     874end;
     875
    735876procedure TExecutor.Run;
    736877begin
  • branches/interpreter2/UGenerator.pas

    r208 r222  
    66
    77uses
    8   Classes, SysUtils, strutils;
     8  Classes, SysUtils, strutils, USource;
    99
    1010type
     
    1717    procedure SetIndent(AValue: Integer);
    1818  public
     19    Name: string;
     20    FileExt: string;
    1921    Output: string;
     22    Prog: TProgram;
    2023    procedure AddText(Text: string);
    2124    procedure AddTextLine(Text: string = '');
    2225    procedure Generate; virtual;
     26    constructor Create; virtual;
     27    destructor Destroy; override;
    2328    property Indent: Integer read FIndent write SetIndent;
    2429  end;
     30
     31  TGeneratorClass = class of TGenerator;
    2532
    2633
     
    5966end;
    6067
     68constructor TGenerator.Create;
     69begin
     70end;
     71
     72destructor TGenerator.Destroy;
     73begin
     74  inherited;
     75end;
     76
    6177end.
    6278
  • branches/interpreter2/UParser.pas

    r221 r222  
    66
    77uses
    8   Classes, SysUtils, Contnrs, UTokenizer, USource;
     8  Classes, SysUtils, UTokenizer, USource;
    99
    1010type
     
    5959      ResultType := TypeBoolean;
    6060    end;
     61    with Functions.AddNew('_NotEqual') do begin
     62      Params.AddNew('A', TypeBoolean);
     63      Params.AddNew('B', TypeBoolean);
     64      ResultType := TypeBoolean;
     65    end;
     66    with Functions.AddNew('_Not') do begin
     67      Params.AddNew('A', TypeBoolean);
     68      ResultType := TypeBoolean;
     69    end;
    6170  end;
    6271  TypeString := Block.Types.AddNew('string');
     
    100109      ResultType := TypeInteger;
    101110    end;
     111    with Functions.AddNew('_Mul') do begin
     112      Params.AddNew('A', TypeInteger);
     113      Params.AddNew('B', TypeInteger);
     114      ResultType := TypeInteger;
     115    end;
     116    with Functions.AddNew('_IntDiv') do begin
     117      Params.AddNew('A', TypeInteger);
     118      Params.AddNew('B', TypeInteger);
     119      ResultType := TypeInteger;
     120    end;
     121    with Functions.AddNew('_Mod') do begin
     122      Params.AddNew('A', TypeInteger);
     123      Params.AddNew('B', TypeInteger);
     124      ResultType := TypeInteger;
     125    end;
    102126    with Functions.AddNew('_Equal') do begin
    103127      Params.AddNew('A', TypeInteger);
     
    109133      Params.AddNew('B', TypeInteger);
    110134      ResultType := TypeBoolean;
     135    end;
     136    with Functions.AddNew('_Lesser') do begin
     137      Params.AddNew('A', TypeInteger);
     138      Params.AddNew('B', TypeInteger);
     139      ResultType := TypeBoolean;
     140    end;
     141    with Functions.AddNew('_Higher') do begin
     142      Params.AddNew('A', TypeInteger);
     143      Params.AddNew('B', TypeInteger);
     144      ResultType := TypeBoolean;
     145    end;
     146    with Functions.AddNew('_LesserOrEqual') do begin
     147      Params.AddNew('A', TypeInteger);
     148      Params.AddNew('B', TypeInteger);
     149      ResultType := TypeBoolean;
     150    end;
     151    with Functions.AddNew('_HigherOrEqual') do begin
     152      Params.AddNew('A', TypeInteger);
     153      Params.AddNew('B', TypeInteger);
     154      ResultType := TypeBoolean;
     155    end;
     156    with Functions.AddNew('_Shr') do begin
     157      Params.AddNew('A', TypeInteger);
     158      Params.AddNew('B', TypeInteger);
     159      ResultType := TypeInteger;
     160    end;
     161    with Functions.AddNew('_Shl') do begin
     162      Params.AddNew('A', TypeInteger);
     163      Params.AddNew('B', TypeInteger);
     164      ResultType := TypeInteger;
     165    end;
     166    with Functions.AddNew('_And') do begin
     167      Params.AddNew('A', TypeInteger);
     168      Params.AddNew('B', TypeInteger);
     169      ResultType := TypeInteger;
     170    end;
     171    with Functions.AddNew('_Or') do begin
     172      Params.AddNew('A', TypeInteger);
     173      Params.AddNew('B', TypeInteger);
     174      ResultType := TypeInteger;
     175    end;
     176    with Functions.AddNew('_Xor') do begin
     177      Params.AddNew('A', TypeInteger);
     178      Params.AddNew('B', TypeInteger);
     179      ResultType := TypeInteger;
    111180    end;
    112181  end;
     
    133202function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;
    134203begin
     204  Result := False;
    135205end;
    136206
  • branches/interpreter2/USource.pas

    r221 r222  
    242242  end;
    243243
    244   TExpressionOperator = (eoAdd, eoSub, eoMultiply, eoDivide, eoModulo, eoAnd, eoXor,
    245     eoOr, eoShl, eoShr, eoEqual, eoNotEqual);
     244  TExpressionOperator = (eoNone, eoAdd, eoSub, eoMultiply, eoDivide, eoIntDivide,
     245    eoModulo, eoAnd, eoXor, eoOr, eoShl, eoShr, eoEqual, eoNotEqual, eoLesser,
     246    eoHigher, eoLesserOrEqual, eoHigherOrEqual, eoNot);
    246247
    247248  { TExpression }
     
    270271  end;
    271272
    272   TExpressionOperandType = (otVariableRef, otConstantRef, otConstantDirect, otFunctionCall);
     273  TExpressionOperandType = (otVariableRef, otConstantRef, otConstantDirect,
     274    otFunctionCall);
    273275
    274276  { TExpressionOperand }
     
    288290    function GetType: TType; override;
    289291    constructor Create;
     292    destructor Destroy; override;
     293  end;
     294
     295  { TExpressionBrackets }
     296
     297  TExpressionBrackets = class(TExpression)
     298    Expression: TExpression;
     299    procedure GetValue(Index: Integer; out Value); override;
     300    function GetField(Index: Integer): TField; override;
     301    procedure SetValue(Index: Integer; var Value); override;
     302    function GetType: TType; override;
    290303    destructor Destroy; override;
    291304  end;
     
    442455      'Integer', 'Float', 'Color', 'Time', 'Date', 'DateTime', 'Enumeration',
    443456      'Reference');
     457    ExpressionOperatorText: array[TExpressionOperator] of string = ('', '+',
     458      '-', '*', '/', 'div', 'mod', 'and', 'xor', 'or', 'shl',
     459      'shr', '=', '<>', '<', '>', '<=','>=', 'not');
     460    ExpressionOperatorFuncText: array[TExpressionOperator] of string = ('', '_Add',
     461      '_Sub', '_Mul', '_Div', '_IntDiv', '_Mod', '_And', '_Xor', '_Or', '_Shl',
     462      '_Shr', '_Equal', '_NotEqual', '_Lesser', '_Higher', '_LesserOrEqual',
     463      '_HigherOrEqual', '_Not');
     464
     465  function GetOperatorByName(Name: string): TExpressionOperator;
    444466
    445467
     
    452474  SYes = 'Yes';
    453475  SNo = 'No';
     476
     477function GetOperatorByName(Name: string): TExpressionOperator;
     478var
     479  I: TExpressionOperator;
     480begin
     481  Result := eoNone;
     482  for I := Succ(Low(TExpressionOperator)) to High(TExpressionOperator) do begin
     483    if ExpressionOperatorText[I] = Name then begin
     484      Result := I;
     485      Break;
     486    end;
     487  end;
     488end;
     489
     490{ TExpressionBrackets }
     491
     492procedure TExpressionBrackets.GetValue(Index: Integer; out Value);
     493begin
     494  if Index = 0 then begin
     495    TExpression(Value) := Expression;
     496  end
     497  else inherited;
     498end;
     499
     500function TExpressionBrackets.GetField(Index: Integer): TField;
     501begin
     502  if Index = 0 then Result := TField.Create(dtObject, 'Expression')
     503  else inherited;
     504end;
     505
     506procedure TExpressionBrackets.SetValue(Index: Integer; var Value);
     507begin
     508  if Index = 0 then begin
     509    Expression := TExpression(Value);
     510  end
     511  else inherited;
     512end;
     513
     514function TExpressionBrackets.GetType: TType;
     515begin
     516  Result := Expression.GetType;
     517end;
     518
     519destructor TExpressionBrackets.Destroy;
     520begin
     521  FreeAndNil(Expression);
     522  inherited;
     523end;
    454524
    455525{ TReturn }
     
    10171087function TExpressionOperation.GetFunctionName: string;
    10181088begin
    1019   if Operation = eoAdd then Result := '_Add'
    1020   else if Operation = eoSub then Result := '_Sub'
    1021   else if Operation = eoEqual then Result := '_Equal'
    1022   else if Operation = eoNotEqual then Result := '_NotEqual'
    1023   else raise Exception.Create('Unsupported operation type.');
     1089  Result := ExpressionOperatorFuncText[Operation];
    10241090end;
    10251091
  • branches/interpreter2/UTokenizer.pas

    r212 r222  
    5353    function GetNext: TToken;
    5454    function CheckNext(Text: string; Kind: TTokenKind): Boolean;
     55    function CheckNextAndRead(Text: string; Kind: TTokenKind): Boolean;
    5556    function CheckNextKind(Kind: TTokenKind): Boolean;
     57    function CheckNextKindAndRead(Kind: TTokenKind): Boolean;
    5658    procedure Expect(Text: string; Kind: TTokenKind);
    5759    procedure Error(Text: string);
     
    111113  Result := (C = ';') or (C = '.') or (C = '(') or (C = ')') or (C = '=') or
    112114    (C = ':') or (C = '+') or (C = '-') or (C = ',') or (C = '/') or
    113     (C = '<') or (C = '>');
     115    (C = '<') or (C = '>') or (C = '*');
    114116end;
    115117
    116118function TTokenizer.IsSpecialSymbol2(Text: string): Boolean;
    117119begin
    118   Result := (Text = ':=') or (Text = '//') or (Text = '<>');
     120  Result := (Text = ':=') or (Text = '//') or (Text = '<>') or (Text = '<=') or
     121    (Text = '>=');
    119122end;
    120123
     
    141144function TTokenizer.IsOperator(Text: string): Boolean;
    142145begin
    143   Result := (Text = '+') or (Text = '-') or (Text = '=') or (Text = '<>');
     146  Result := (Text = '+') or (Text = '-') or (Text = '=') or (Text = '<>') or
     147    (Text = '*') or (Text = '/') or (Text = 'div') or (Text = '<=') or
     148    (Text = '>=') or (Text = 'mod') or (Text = 'shl') or (Text = 'shr') or
     149    (Text = 'and') or (Text = 'or') or (Text = 'xor') or (Text = 'not') or
     150    (Text = '>') or (Text = '<');
    144151end;
    145152
     
    270277end;
    271278
     279function TTokenizer.CheckNextAndRead(Text: string; Kind: TTokenKind): Boolean;
     280var
     281  LastPos: TTokenizerPos;
     282  Token: TToken;
     283begin
     284  LastPos := Pos;
     285  Token := GetNext;
     286  Result := (Token.Text = Text) and (Token.Kind = Kind);
     287  if not Result then Pos := LastPos;
     288end;
     289
    272290function TTokenizer.CheckNextKind(Kind: TTokenKind): Boolean;
    273291var
     
    281299end;
    282300
     301function TTokenizer.CheckNextKindAndRead(Kind: TTokenKind): Boolean;
     302var
     303  LastPos: TTokenizerPos;
     304  Token: TToken;
     305begin
     306  LastPos := Pos;
     307  Token := GetNext;
     308  Result := Token.Kind = Kind;
     309  if not Result then Pos := LastPos;
     310end;
     311
    283312procedure TTokenizer.Expect(Text: string; Kind: TTokenKind);
    284313var
Note: See TracChangeset for help on using the changeset viewer.