Changeset 212


Ignore:
Timestamp:
Apr 22, 2020, 12:04:22 PM (4 years ago)
Author:
chronos
Message:
  • Added: Support for custom functions.
Location:
branches/interpreter2
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter2/Test.pas

    r205 r212  
    88const
    99  C: Integer = 1;
     10
     11function IsZero(A: Integer): Boolean;
     12begin
     13  Result := A = 0;
     14end;
     15
    1016begin 
    1117  X := 'A' + 'B';
  • branches/interpreter2/UExecutor.pas

    r211 r212  
    630630  FuncName: string;
    631631begin
    632   if Expression.Operation = eoAdd then FuncName := '_Add'
    633   else if Expression.Operation = eoSub then FuncName := '_Sub'
    634   else if Expression.Operation = eoEqual then FuncName := '_Equal'
    635   else if Expression.Operation = eoNotEqual then FuncName := '_NotEqual'
    636   else raise Exception.Create('Unsupported operation type.');
    637 
    638   ExecutorFunction := Block.GetTypeFunction(Expression.TypeRef, FuncName);
     632  FuncName := Expression.GetFunctionName;
     633
     634  ExecutorFunction := Block.GetTypeFunction(Expression.FunctionRef.ParentType, FuncName);
     635  if not Assigned(ExecutorFunction) then
     636    raise Exception.Create('Missing operator function ' + FuncName + ' for type ' + Expression.TypeRef.Name);
     637
    639638  Result := Expression.TypeRef.ValueClass.Create;
    640639
  • branches/interpreter2/UGeneratorCSharp.pas

    r208 r212  
    1515  private
    1616    procedure GenerateProgram(Block: TBlock;  Prog:TProgram);
     17    procedure GenerateFunction(ParentBlock: TBlock; FunctionDef: TFunction);
    1718    procedure GenerateBlock(ParentBlock: TBlock; Block: TBlock);
    1819    procedure GenerateBlockConst(ParentBlock: TBlock; Block: TBlock);
     
    209210  Indent := Indent + 1;
    210211  GenerateBlock(nil, Prog.SystemBlock);
     212  AddTextLine('public static void Main()');
     213  AddTextLine('{');
     214  AddTextLine('  ' + Prog.Name + ' app = new ' + Prog.Name + '();');
     215  AddTextLine('  app.Entry();');
     216  AddTextLine('}');
     217  AddTextLine();
     218  AddTextLine('public void Entry()');
    211219  GenerateBlock(Block, Prog.Block);
    212220  Indent := Indent - 1;
     
    216224procedure TGeneratorCSharp.GenerateBlock(ParentBlock: TBlock; Block: TBlock);
    217225begin
    218   GenerateBlockVar(ParentBlock, Block);
    219   GenerateBlockConst(ParentBlock, Block);
    220   GenerateBlockFunctions(ParentBlock, Block);
    221   if ParentBlock = Prog.SystemBlock then
    222     AddTextLine('public static void Main()');
     226  GenerateBlockVar(Block, Block);
     227  GenerateBlockConst(Block, Block);
     228  GenerateBlockFunctions(Block, Block);
    223229  if Block.BeginEnd.Commands.Count > 0 then begin
    224230    GenerateBeginEnd(ParentBlock, Block.BeginEnd);
     
    234240  for I := 0 to Block.Constants.Count - 1 do begin
    235241    Constant := TConstant(Block.Constants[I]);
    236     AddText('static ');
    237242    GenerateTypeRef(Constant.TypeRef);
    238243    AddText(' ' + Constant.Name + ' = ');
     
    248253begin
    249254  if Block.Variables.Count > 0 then begin
    250     for I := 0 to Block.Variables.Count - 1 do begin
     255    for I := 0 to Block.Variables.Count - 1 do
     256    if not TVariable(Block.Variables[I]).Internal then begin
    251257      Variable := TVariable(Block.Variables[I]);
    252       AddText('static ');
    253258      GenerateTypeRef(Variable.TypeRef);
    254259      AddTextLine(' ' + Variable.Name + ';');
     
    258263end;
    259264
     265procedure TGeneratorCSharp.GenerateFunction(ParentBlock: TBlock;
     266  FunctionDef: TFunction);
     267var
     268  I: Integer;
     269begin
     270  GenerateTypeRef(FunctionDef.ResultType);
     271  AddText(' ' + FunctionDef.Name + '(');
     272  for I := 0 to FunctionDef.Params.Count - 1 do begin
     273    GenerateTypeRef(TFunctionParameter(FunctionDef.Params[I]).TypeRef);
     274    AddText(' ');
     275    AddText(TFunctionParameter(FunctionDef.Params[I]).Name);
     276    if I > 0 then AddText(', ');
     277  end;
     278  AddTextLine(')');
     279  if FunctionDef.InternalName <> '' then begin
     280    AddTextLine('{');
     281    Indent := Indent + 1;
     282    if FunctionDef.InternalName = 'WriteLn' then AddTextLine('Console.Write(Text + "\n");')
     283    else if FunctionDef.InternalName = 'Write' then AddTextLine('Console.Write(Text);')
     284    else if FunctionDef.InternalName = 'IntToStr' then AddTextLine('return Value.ToString();')
     285    else if FunctionDef.InternalName = 'StrToInt' then begin
     286      AddTextLine('int x = 0;');
     287      AddTextLine('if (int.TryParse(Value, out x))');
     288      AddTextLine('{');
     289      AddTextLine('  return x;');
     290      AddTextLine('} else return 0;');
     291    end;
     292
     293    Indent := Indent - 1;
     294    AddTextLine('}');
     295  end else begin
     296    GenerateBlock(ParentBlock, FunctionDef.Block);
     297    AddTextLine;
     298  end;
     299end;
     300
    260301procedure TGeneratorCSharp.GenerateBlockFunctions(ParentBlock: TBlock;
    261302  Block: TBlock);
    262303var
    263304  I: Integer;
    264   J: Integer;
    265   FunctionDef: TFunction;
    266305begin
    267306  for I := 0 to Block.Functions.Count - 1 do begin
    268     FunctionDef := TFunction(Block.Functions[I]);
    269     AddText('static ');
    270     GenerateTypeRef(FunctionDef.ResultType);
    271     AddText(' ' + FunctionDef.Name + '(');
    272     for J := 0 to FunctionDef.Params.Count - 1 do begin
    273       GenerateTypeRef(TFunctionParameter(FunctionDef.Params[J]).TypeRef);
    274       AddText(' ');
    275       AddText(TFunctionParameter(FunctionDef.Params[J]).Name);
    276       if J > 0 then AddText(', ');
    277     end;
    278     AddTextLine(')');
    279     if FunctionDef.InternalName <> '' then begin
    280       AddTextLine('{');
    281       Indent := Indent + 1;
    282       if FunctionDef.InternalName = 'WriteLn' then AddTextLine('Console.Write(Text + "\n");')
    283       else if FunctionDef.InternalName = 'Write' then AddTextLine('Console.Write(Text);')
    284       else if FunctionDef.InternalName = 'IntToStr' then AddTextLine('return Value.ToString();')
    285       else if FunctionDef.InternalName = 'StrToInt' then begin
    286         AddTextLine('int x = 0;');
    287         AddTextLine('if (int.TryParse(Value, out x))');
    288         AddTextLine('{');
    289         AddTextLine('  return x;');
    290         AddTextLine('} else return 0;');
    291       end;
    292 
    293       Indent := Indent - 1;
    294       AddTextLine('}');
    295     end else begin
    296       GenerateBeginEnd(ParentBlock, FunctionDef.BeginEnd);
    297       AddTextLine;
    298     end;
     307    GenerateFunction(ParentBlock, TFunction(Block.Functions[I]));
    299308    AddTextLine;
    300309  end;
  • branches/interpreter2/UGeneratorPascal.pas

    r208 r212  
    1515  private
    1616    procedure GenerateProgram(Block: TBlock;  Prog:TProgram);
     17    procedure GenerateFunction(ParentBlock: TBlock; FunctionDef: TFunction);
    1718    procedure GenerateBlock(ParentBlock: TBlock; Block: TBlock);
    1819    procedure GenerateBlockVar(ParentBlock: TBlock; Block: TBlock);
    1920    procedure GenerateBlockConst(ParentBlock: TBlock; Block: TBlock);
     21    procedure GenerateBlockFunctions(ParentBlock: TBlock; Block: TBlock);
    2022    procedure GenerateBeginEnd(Block: TBlock; BeginEnd: TBeginEnd);
    2123    procedure GenerateCommand(Block: TBlock; Command: TCommand);
     
    188190begin
    189191  if Prog.Name <> '' then AddTextLine('program ' + Prog.Name + ';');
     192  AddTextLine('{$mode delphi}');
     193  AddTextLine('uses SysUtils;');
    190194  GenerateBlock(Block, Prog.Block);
    191195  AddTextLine('.');
    192196end;
    193197
     198procedure TGeneratorPascal.GenerateFunction(ParentBlock: TBlock;
     199  FunctionDef: TFunction);
     200var
     201  I: Integer;
     202begin
     203  AddText('function ' + FunctionDef.Name);
     204  if FunctionDef.Params.Count > 0 then begin
     205    AddText('(');
     206    for I := 0 to FunctionDef.Params.Count - 1 do begin
     207      AddText(TFunctionParameter(FunctionDef.Params[I]).Name);
     208      AddText(': ');
     209      AddText(TFunctionParameter(FunctionDef.Params[I]).TypeRef.Name);
     210      if I > 0 then AddText(', ');
     211    end;
     212    AddText(')');
     213  end;
     214  if Assigned(FunctionDef.ResultType) then begin
     215    AddText(': ');
     216    AddText(FunctionDef.ResultType.Name);
     217  end;
     218  AddTextLine(';');
     219  if FunctionDef.InternalName <> '' then begin
     220    AddTextLine('begin');
     221    Indent := Indent + 1;
     222    if FunctionDef.InternalName = 'WriteLn' then AddTextLine('System.WriteLn(Text);')
     223    else if FunctionDef.InternalName = 'Write' then AddTextLine('System.Write(Text);')
     224    else if FunctionDef.InternalName = 'IntToStr' then AddTextLine('return SysUtils.IntToStr(Value);')
     225    else if FunctionDef.InternalName = 'StrToInt' then AddTextLine('return SysUtils.StrToInt(Value);');
     226    Indent := Indent - 1;
     227    AddTextLine('end;');
     228  end else begin
     229    GenerateBlock(ParentBlock, FunctionDef.Block);
     230    AddTextLine(';');
     231  end;
     232end;
     233
    194234procedure TGeneratorPascal.GenerateBlock(ParentBlock: TBlock; Block: TBlock);
    195235begin
    196236  GenerateBlockConst(ParentBlock, Block);
    197237  GenerateBlockVar(ParentBlock, Block);
     238  GenerateBlockFunctions(ParentBlock, Block);
    198239  GenerateBeginEnd(ParentBlock, Block.BeginEnd);
    199240end;
     
    203244  I: Integer;
    204245  Variable: TVariable;
    205 begin
    206   if Block.Variables.Count > 0 then begin
     246  VarCount: Integer;
     247begin
     248  VarCount := 0;
     249  for I := 0 to Block.Variables.Count - 1 do
     250    if not TVariable(Block.Variables[I]).Internal then Inc(VarCount);
     251
     252  if VarCount > 0 then begin
    207253    AddTextLine('var');
    208254    Indent := Indent + 1;
    209     for I := 0 to Block.Variables.Count - 1 do begin
     255    for I := 0 to Block.Variables.Count - 1 do
     256    if not TVariable(Block.Variables[I]).Internal then begin
    210257      Variable := TVariable(Block.Variables[I]);
    211258      AddTextLine(Variable.Name + ': ' + Variable.TypeRef.Name + ';');
     
    249296end;
    250297
     298procedure TGeneratorPascal.GenerateBlockFunctions(ParentBlock: TBlock;
     299  Block: TBlock);
     300var
     301  I: Integer;
     302begin
     303  for I := 0 to Block.Functions.Count - 1 do begin
     304    GenerateFunction(ParentBlock, TFunction(Block.Functions[I]));
     305    AddTextLine;
     306  end;
     307end;
     308
    251309procedure TGeneratorPascal.Generate;
    252310begin
  • branches/interpreter2/UGeneratorPhp.pas

    r208 r212  
    1515  private
    1616    procedure GenerateProgram(Block: TBlock;  Prog:TProgram);
     17    procedure GenerateFunction(ParentBlock: TBlock; FunctionDef: TFunction);
    1718    procedure GenerateBlock(ParentBlock: TBlock; Block: TBlock);
    1819    procedure GenerateBlockConst(ParentBlock: TBlock; Block: TBlock);
     
    201202end;
    202203
     204procedure TGeneratorPhp.GenerateFunction(ParentBlock: TBlock;
     205  FunctionDef: TFunction);
     206var
     207  I: Integer;
     208begin
     209  AddText('function ' + FunctionDef.Name + '(');
     210  for I := 0 to FunctionDef.Params.Count - 1 do begin
     211    AddText('$' + TFunctionParameter(FunctionDef.Params[I]).Name);
     212    if I > 0 then AddText(', ');
     213  end;
     214  AddTextLine(')');
     215  if FunctionDef.InternalName <> '' then begin
     216    AddTextLine('{');
     217    Indent := Indent + 1;
     218    if FunctionDef.InternalName = 'WriteLn' then AddTextLine('echo($Text."\n");')
     219    else if FunctionDef.InternalName = 'Write' then AddTextLine('echo($Text);')
     220    else if FunctionDef.InternalName = 'IntToStr' then AddTextLine('return $Value;')
     221    else if FunctionDef.InternalName = 'StrToInt' then AddTextLine('return $Value;');
     222    Indent := Indent - 1;
     223    AddTextLine('}');
     224  end else begin
     225    GenerateBlock(ParentBlock, FunctionDef.Block);
     226    AddTextLine;
     227  end;
     228end;
     229
    203230procedure TGeneratorPhp.GenerateBlock(ParentBlock: TBlock; Block: TBlock);
    204231begin
     
    228255var
    229256  I: Integer;
    230   J: Integer;
    231   FunctionDef: TFunction;
    232257begin
    233258  for I := 0 to Block.Functions.Count - 1 do begin
    234     FunctionDef := TFunction(Block.Functions[I]);
    235     AddText('function ' + FunctionDef.Name + '(');
    236     for J := 0 to FunctionDef.Params.Count - 1 do begin
    237       AddText('$' + TFunctionParameter(FunctionDef.Params[J]).Name);
    238       if J > 0 then AddText(', ');
    239     end;
    240     AddTextLine(')');
    241     if FunctionDef.InternalName <> '' then begin
    242       AddTextLine('{');
    243       Indent := Indent + 1;
    244       if FunctionDef.InternalName = 'WriteLn' then AddTextLine('echo($Text."\n");')
    245       else if FunctionDef.InternalName = 'Write' then AddTextLine('echo($Text);')
    246       else if FunctionDef.InternalName = 'IntToStr' then AddTextLine('return $Value;')
    247       else if FunctionDef.InternalName = 'StrToInt' then AddTextLine('return $Value;');
    248       Indent := Indent - 1;
    249       AddTextLine('}');
    250     end else begin
    251       GenerateBeginEnd(ParentBlock, FunctionDef.BeginEnd);
    252       AddTextLine;
    253     end;
     259    GenerateFunction(ParentBlock, TFunction(Block.Functions[I]));
    254260    AddTextLine;
    255261  end;
  • branches/interpreter2/UParser.pas

    r211 r212  
    2020    function ParseCommand(Block: TBlock; out Command: TCommand): Boolean;
    2121    function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;
    22     function ParseBlock(ParentBlock: TBlock; out Block: TBlock): Boolean;
     22    function ParseBlock(ParentBlock: TBlock; out Block: TBlock; ExistingBlock: TBlock = nil): Boolean;
    2323    function ParseBlockVar(Block: TBlock): Boolean;
    2424    function ParseBlockConst(Block: TBlock): Boolean;
     25    function ParseFunction(Block: TBlock; out Func: TFunction): Boolean;
     26    function ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter): Boolean;
    2527    function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean;
    2628    function ParseExpression(Block: TBlock; out Expression: TExpression): Boolean;
     
    194196end;
    195197
    196 function TParser.ParseBlock(ParentBlock: TBlock; out Block: TBlock): Boolean;
     198function TParser.ParseBlock(ParentBlock: TBlock; out Block: TBlock; ExistingBlock: TBlock = nil): Boolean;
    197199var
    198200  BeginEnd: TBeginEnd;
    199 begin
    200   Result := False;
    201   Block := TBlock.Create;
     201  Func: TFunction;
     202begin
     203  Result := False;
     204  if Assigned(ExistingBlock) then Block := ExistingBlock
     205    else Block := TBlock.Create;
    202206  Block.ParentBlock := ParentBlock;
    203   ParseBlockVar(Block);
    204   ParseBlockConst(Block);
     207  while True do begin
     208    if ParseBlockVar(Block) then begin
     209    end else
     210    if ParseBlockConst(Block) then begin
     211    end else
     212    if ParseFunction(Block, Func) then begin
     213      Block.Functions.Add(Func);
     214    end else begin
     215      Break;
     216    end;
     217  end;
    205218  if ParseBeginEnd(Block, BeginEnd) then begin
    206219    Result := True;
     
    208221    Block.BeginEnd := BeginEnd;
    209222    BeginEnd.Parent := Block;
    210   end else Block.Free;
     223  end else begin
     224    if not Assigned(ExistingBlock) then Block.Free;
     225    Block := nil;
     226  end;
    211227end;
    212228
     
    291307end;
    292308
     309function TParser.ParseFunction(Block: TBlock; out Func: TFunction): Boolean;
     310var
     311  Token: TToken;
     312  FunctionParameter: TFunctionParameter;
     313  NewBlock: TBlock;
     314  TypeRef: TType;
     315  Variable: TVariable;
     316  I: Integer;
     317begin
     318  Result := False;
     319  if Tokenizer.CheckNext('function', tkKeyword) then begin
     320    Tokenizer.Expect('function', tkKeyword);
     321    Result := True;
     322    Func := TFunction.Create;
     323    Token := Tokenizer.GetNext;
     324    if Token.Kind = tkIdentifier then begin
     325      Func.Name := Token.Text;
     326      if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin
     327        Tokenizer.Expect('(', tkSpecialSymbol);
     328        while not Tokenizer.CheckNext(')', tkSpecialSymbol) do begin
     329          if Func.Params.Count > 0 then Tokenizer.Expect(',', tkSpecialSymbol);
     330          if ParseFunctionParameter(Block, FunctionParameter) then begin
     331            Func.Params.Add(FunctionParameter);
     332          end else Error('Expected function parameter.');
     333        end;
     334        Tokenizer.Expect(')', tkSpecialSymbol);
     335        for I := 0 to Func.Params.Count - 1 do begin
     336          Variable := TVariable.Create;
     337          Variable.Name := TFunctionParameter(Func.Params[I]).Name;
     338          Variable.TypeRef := TFunctionParameter(Func.Params[I]).TypeRef;
     339          Variable.Internal := True;
     340          Func.Block.Variables.Add(Variable);
     341        end;
     342      end;
     343      if Tokenizer.CheckNext(':', tkSpecialSymbol) then begin
     344        Tokenizer.Expect(':', tkSpecialSymbol);
     345        Token := Tokenizer.GetNext;
     346        if Token.Kind = tkIdentifier then begin
     347          TypeRef := Block.GetType(Token.Text);
     348          if Assigned(TypeRef) then begin
     349            Func.ResultType := TypeRef;
     350            Variable := TVariable.Create;
     351            Variable.Name := 'Result';
     352            Variable.TypeRef := TypeRef;
     353            Variable.Internal := True;
     354            Func.Block.Variables.Add(Variable);
     355          end else Error('Type ' + Token.Text + ' not found');
     356        end;
     357      end;
     358      Tokenizer.Expect(';', tkSpecialSymbol);
     359      if ParseBlock(Block, NewBlock, Func.Block) then begin
     360        Tokenizer.Expect(';', tkSpecialSymbol);
     361      end else Error('Expected function block');
     362    end else Error('Expected function name');
     363  end;
     364end;
     365
     366function TParser.ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter
     367  ): Boolean;
     368var
     369  Token: TToken;
     370  TypeRef: TType;
     371begin
     372  Result := True;
     373  Token := Tokenizer.GetNext;
     374  if Token.Kind = tkIdentifier then begin
     375    Parameter := TFunctionParameter.Create;
     376    Parameter.Name := Token.Text;
     377    Tokenizer.Expect(':', tkSpecialSymbol);
     378    Token := Tokenizer.GetNext;
     379    if Token.Kind = tkIdentifier then begin
     380      TypeRef := Block.GetType(Token.Text);
     381      if Assigned(TypeRef) then begin
     382        Parameter.TypeRef := TypeRef;
     383      end else Error('Type ' + Token.Text + ' not found');
     384    end else Error('Expected parameter type');
     385  end else Error('Expected parameter name');
     386end;
     387
    293388function TParser.ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean;
    294389var
     
    315410        end else begin
    316411          Result := False;
    317           Error('Assignment type mismatch.');
     412          Error('Assignment type mismatch. Expected ' + Variable.TypeRef.Name + ' but got ' + Expression.GetType.Name);
    318413        end;
    319414      end;
     
    348443  Expression: TExpression;
    349444  LastPos: TTokenizerPos;
     445  I: Integer;
     446  ExpectedType: TType;
    350447begin
    351448  Result := False;
     
    362459      else if Token.Text = '<>' then ExpressionOperation.Operation := eoNotEqual
    363460      else Error('Unsupported operator ' + Token.Text);
     461      ExpressionOperation.FunctionRef := ExpressionOperation.TypeRef.Functions.SearchByName(ExpressionOperation.GetFunctionName);
     462      if not Assigned(ExpressionOperation.FunctionRef.ResultType) then
     463        raise Exception.Create('Missing result type for function');
     464      ExpressionOperation.TypeRef := ExpressionOperation.FunctionRef.ResultType;
    364465      ExpressionOperation.Items.Add(Operand);
     466      I := 1;
    365467      if ParseExpression(Block, Expression) then begin
    366         if Expression.GetType = Operand.GetType then
     468        ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef;
     469        if Expression.GetType = ExpectedType then
    367470          ExpressionOperation.Items.Add(Expression)
    368           else Error('Expression operands needs to be same type.');
     471          else Error('Expression operands needs to be same type. Expected ' + ExpectedType.Name + ' but found ' + Expression.GetType.Name);
    369472      end else Error('Missing operand.');
    370473    end else Operand.Free;
  • branches/interpreter2/USource.pas

    r211 r212  
    1212  TFunctions = class;
    1313  TBeginEnd = class;
     14  TBlock = class;
    1415
    1516  TDataType = (dtNone, dtString, dtBoolean, dtInteger, dtFloat, dtColor,
     
    129130    Name: string;
    130131    TypeRef: TType;
     132    Internal: Boolean;
    131133    procedure GetValue(Index: Integer; out Value); override;
    132134    function GetField(Index: Integer): TField; override;
     
    183185    Params: TFunctionParameters;
    184186    ResultType: TType;
    185     BeginEnd: TBeginEnd;
     187    Block: TBlock;
     188    ParentType: TType;
    186189    procedure GetValue(Index: Integer; out Value); override;
    187190    function GetField(Index: Integer): TField; override;
     
    194197
    195198  TFunctions = class(TSourceNodes)
     199    ParentType: TType;
    196200    function SearchByName(Name: string): TFunction;
    197201    function AddNew(Name: string): TFunction;
     
    253257  public
    254258    TypeRef: TType;
     259    FunctionRef: TFunction;
    255260    Operation: TExpressionOperator;
    256261    Items: TExpressions;
     262    function GetFunctionName: string;
    257263    procedure GetValue(Index: Integer; out Value); override;
    258264    function GetField(Index: Integer): TField; override;
     
    839845procedure TFunction.GetValue(Index: Integer; out Value);
    840846begin
    841   if Index = 0 then TBeginEnd(Value) := BeginEnd
     847  if Index = 0 then TBlock(Value) := Block
    842848  else if Index = 1 then TFunctionParameters(Value) := Params
    843849  else if Index = 2 then TType(Value) := ResultType
     
    862868procedure TFunction.SetValue(Index: Integer; var Value);
    863869begin
    864   if Index = 0 then BeginEnd := TBeginEnd(Value)
     870  if Index = 0 then Block := TBlock(Value)
    865871  else if Index = 1 then Params := TFunctionParameters(Value)
    866872  else if Index = 2 then ResultType := TType(Value)
     
    872878begin
    873879  Params := TFunctionParameters.Create;
    874   BeginEnd := TBeginEnd.Create;
     880  Block := TBlock.Create;
    875881end;
    876882
    877883destructor TFunction.Destroy;
    878884begin
    879   BeginEnd.Free;
     885  Block.Free;
    880886  Params.Free;
    881887  inherited Destroy;
     
    910916begin
    911917  Functions := TFunctions.Create;
     918  Functions.ParentType := Self;
    912919end;
    913920
     
    950957end;
    951958
     959function TExpressionOperation.GetFunctionName: string;
     960begin
     961  if Operation = eoAdd then Result := '_Add'
     962  else if Operation = eoSub then Result := '_Sub'
     963  else if Operation = eoEqual then Result := '_Equal'
     964  else if Operation = eoNotEqual then Result := '_NotEqual'
     965  else raise Exception.Create('Unsupported operation type.');
     966end;
     967
    952968function TExpressionOperation.GetFieldsCount: Integer;
    953969begin
     
    11591175  Result := TFunction.Create;
    11601176  Result.Name := Name;
     1177  Result.ParentType := ParentType;
    11611178  Add(Result);
    11621179end;
     
    12421259  Result := Types.SearchByName(Name);
    12431260  if not Assigned(Result) and Assigned(ParentBlock) then
    1244     Result := ParentBlock.Types.SearchByName(Name);
     1261    Result := ParentBlock.GetType(Name);
    12451262end;
    12461263
     
    12491266  Result := Constants.SearchByName(Name);
    12501267  if not Assigned(Result) and Assigned(ParentBlock) then
    1251     Result := ParentBlock.Constants.SearchByName(Name);
     1268    Result := ParentBlock.GetConstant(Name);
    12521269end;
    12531270
     
    12561273  Result := Variables.SearchByName(Name);
    12571274  if not Assigned(Result) and Assigned(ParentBlock) then
    1258     Result := ParentBlock.Variables.SearchByName(Name);
     1275    Result := ParentBlock.GetVariable(Name);
    12591276end;
    12601277
     
    12631280  Result := Functions.SearchByName(Name);
    12641281  if not Assigned(Result) and Assigned(ParentBlock) then
    1265     Result := ParentBlock.Functions.SearchByName(Name);
     1282    Result := ParentBlock.GetFunction(Name);
    12661283end;
    12671284
     
    12691286begin
    12701287  Constants := TConstants.Create;
     1288  Constants.Parent := Self;
    12711289  Variables := TVariables.Create;
     1290  Variables.Parent := Self;
    12721291  Functions := TFunctions.Create;
     1292  Functions.Parent := Self;
    12731293  Types := TTypes.Create;
     1294  Types.Parent := Self;
    12741295  BeginEnd := TBeginEnd.Create;
     1296  BeginEnd.Parent := Self;
    12751297end;
    12761298
  • branches/interpreter2/UTokenizer.pas

    r207 r212  
    150150  (Text = 'else') or (Text = 'while') or (Text = 'do') or (Text = 'for') or
    151151  (Text = 'to') or (Text = 'repeat') or (Text = 'until') or (Text = 'break') or
    152   (Text = 'continue');
     152  (Text = 'continue') or (Text = 'function');
    153153end;
    154154
Note: See TracChangeset for help on using the changeset viewer.