Changeset 100 for branches/interpreter
- Timestamp:
- Feb 11, 2017, 12:47:38 PM (8 years ago)
- Location:
- branches/interpreter
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/interpreter/Execute3.pas
r99 r100 109 109 begin 110 110 case Command^.CmdType of 111 ctBeginEnd: ExecuteBeginEnd( PBeginEnd(Command^.Ptr));112 ctWhileDo: ExecuteWhileDo( PWhileDo(Command^.Ptr));113 ctIfThenElse: ExecuteIfThenElse( PIfThenElse(Command^.Ptr));114 ctExecution: ExecuteExecution( PExecution(Command^.Ptr));115 ctAssignment: ExecuteAssignment( PAssignment(Command^.Ptr));111 ctBeginEnd: ExecuteBeginEnd(Command^.BeginEnd); 112 ctWhileDo: ExecuteWhileDo(Command^.WhileDo); 113 ctIfThenElse: ExecuteIfThenElse(Command^.IfThenElse); 114 ctExecution: ExecuteExecution(Command^.Execution); 115 ctAssignment: ExecuteAssignment(Command^.Assignment); 116 116 end; 117 117 end; -
branches/interpreter/Parser3.pas
r99 r100 14 14 15 15 type 16 TTokenType = (ttNormal, ttSpecialSymbol, ttString, ttConstant );16 TTokenType = (ttNormal, ttSpecialSymbol, ttString, ttConstant, ttNumber, ttChar); 17 17 18 18 var … … 22 22 23 23 MainProgram: PProgramCode; 24 FunctionContext: PFunction; 24 25 25 26 function ParseIfThen(IfThenElse: PIfThenElse): Boolean; forward; … … 27 28 function ParseExecution(Execution: PExecution): Boolean; forward; 28 29 function ParseBeginEnd(BeginEnd: PBeginEnd): Boolean; forward; 29 function ParseGetValue(GetValue: PGetValue ): Boolean; forward;30 function ParseGetValue(GetValue: PGetValue; NoExpression: Boolean = False): Boolean; forward; 30 31 31 32 … … 33 34 begin 34 35 Result := (C = ' ') or (C = #13) or (C = #10) or (C = #9); 36 end; 37 38 function IsDigit(C: Char): Boolean; 39 begin 40 Result := (C >= '0') and (C <= '9'); 35 41 end; 36 42 … … 72 78 end; 73 79 80 function StrToInt(S: string): Integer; 81 var 82 I: Integer; 83 N: Integer; 84 begin 85 Result := 0; 86 N := 1; 87 I := Length(S); 88 while I >= 1 do begin 89 Result := Result + (Ord(S[I]) - Ord('0')) * N; 90 N := N * 10; 91 I := I - 1; 92 end; 93 end; 94 74 95 function ReadNext: string; 75 96 var 76 97 C: Char; 77 IsString: Boolean;78 98 begin 79 99 Result := ''; 80 IsString := False;81 100 LastTokenType := ttNormal; 82 101 repeat 83 102 C := ReadChar; 84 if IsString then begin103 if LastTokenType = ttString then begin 85 104 if C = '''' then begin 105 Break; 106 end else Result := Result + C; 107 end else 108 if LastTokenType = ttNumber then begin 109 if not IsDigit(C) then begin 110 if Result[1] = '#' then begin 111 Result := Chr(StrToInt(Copy(Result, 2, Length(Result)))); 112 LastTokenType := ttChar; 113 end; 114 InputTextPos := InputTextPos - 1; 86 115 Break; 87 116 end else Result := Result + C; … … 108 137 end; 109 138 end else 139 if C = '#' then begin 140 Result := Result + '#'; 141 LastTokenType := ttNumber; 142 end else 110 143 if C = '''' then begin 111 144 LastTokenType := ttString; 112 IsString := True;113 145 end else begin 114 146 Result := Result + C; … … 157 189 OldPos := InputTextPos; 158 190 Next := ReadNext; 159 Variable := MainProgram^.Variables.GetByName(Next); 191 if FunctionContext = nil then 192 Variable := MainProgram^.Variables.GetByName(Next) 193 else Variable := FunctionContext^.Variables.GetByName(Next); 160 194 if Variable <> nil then begin 161 195 Result := True; … … 182 216 end; 183 217 218 function GetOperatorType(Name: string): TOperator; 219 var 220 I: Integer; 221 begin 222 I := 0; 223 while (I < Length(OperatorString)) and (OperatorString[TOperator(I)] <> Name) do Inc(I); 224 if I < Length(OperatorString) then Result := TOperator(I) 225 else Result := opNone; 226 end; 227 228 function ParseOperator(out ExpOperator: TOperator): Boolean; 229 var 230 OldPos: Integer; 231 OperatorName: string; 232 begin 233 OldPos := InputTextPos; 234 OperatorName := ReadNext; 235 ExpOperator := GetOperatorType(OperatorName); 236 if ExpOperator <> opNone then begin 237 Result := True; 238 239 end else begin 240 InputTextPos := OldPos; 241 Result := False; 242 end; 243 end; 244 245 function ParseValue(Value: PConstant): Boolean; 246 var 247 OldPos: Integer; 248 Text: string; 249 begin 250 Result := True; 251 OldPos := InputTextPos; 252 Text := ReadNext; 253 if LastTokenType = ttString then begin 254 Value.DataType := MainProgram.Types.GetByName('string'); 255 Value.ValueString := Text; 256 end else 257 if LastTokenType = ttChar then begin 258 Value.DataType := MainProgram.Types.GetByName('Char'); 259 Value.ValueChar := Text[1]; 260 end else 261 if LastTokenType = ttNumber then begin 262 Value.DataType := MainProgram.Types.GetByName('Integer'); 263 //Value.ValueInteger := StrToInt(Text); 264 end else begin 265 Result := False; 266 InputTextPos := OldPos; 267 end; 268 end; 269 270 procedure DeleteExpressionItem(Expression: PExpression; Index: Integer); 271 var 272 I: Integer; 273 begin 274 I := Index; 275 while (I + 1) < Length(Expression^.Items) do begin 276 Expression^.Items[I] := Expression^.Items[I + 1]; 277 I := I + 1; 278 end; 279 SetLength(Expression^.Items, Length(Expression^.Items) - 1); 280 end; 281 184 282 function ParseExpression(Expression: PExpression): Boolean; 185 283 var 186 Next: string;187 OldPos: Integer;188 R: Boolean;189 284 GetValue: TGetValue; 190 Execution: TExecution; 191 Variable: PVariable; 285 ExpOperator: TOperator; 192 286 SubExpression: TExpression; 287 I: Integer; 288 II: Integer; 193 289 begin 194 290 Result := True; 195 if CheckNext('not') then begin 196 Expect('not'); 197 end; 198 if CheckNext('(') then begin 199 Expect('('); 200 if ParseGetValue(@GetValue) then begin 291 repeat 292 if CheckNext('(') then begin 293 Expect('('); 294 if ParseExpression(@SubExpression) then begin 295 SetLength(Expression^.Items, Length(Expression^.Items) + 1); 296 Expression^.Items[Length(Expression^.Items) - 1] := SubExpression; 297 end; 298 Expect(')'); 299 end else 300 if ParseOperator(ExpOperator) then begin 201 301 SetLength(Expression^.Items, Length(Expression^.Items) + 1); 202 Expression^.Items[Length(Expression^.Items) - 1] := GetValue; 302 Expression^.Items[Length(Expression^.Items) - 1].NodeType := ntOperator; 303 Expression^.Items[Length(Expression^.Items) - 1].OperatorType := ExpOperator; 304 end else 305 if ParseGetValue(@GetValue, True) then begin 306 SetLength(Expression^.Items, Length(Expression^.Items) + 1); 307 Expression^.Items[Length(Expression^.Items) - 1].NodeType := ntValue; 308 Expression^.Items[Length(Expression^.Items) - 1].Value := GetValue; 309 end else begin 310 Result:= True; 311 Break; 203 312 end; 204 Expect(')'); 205 end else 206 if ParseVariable(Variable) then begin 207 OldPos := InputTextPos; 208 Next := ReadNext; 209 if IsOperator(Next) then begin 210 Next := ReadNext; 211 //if IsVariable(Next) then begin 212 213 //end else ShowError('Expected variable'); 214 end else InputTextPos := OldPos; 215 end else 216 if LastTokenType = ttString then begin 217 ReadNext 218 end else 219 if ParseExecution(@Execution) then begin 220 end else 221 ShowError('Expected variable but found ' + ReadNext); 222 223 OldPos := InputTextPos; 224 Next := ReadNext; 225 if IsLogicOperator(Next) or IsOperator(Next) then begin 226 R := ParseExpression(@SubExpression); 227 end else InputTextPos := OldPos; 228 end; 229 230 function ParseGetValue(GetValue: PGetValue): Boolean; 313 until False; 314 315 if Length(Expression^.Items) > 0 then begin 316 // Build expression tree using operator precedence 317 for II := 0 to Length(OperatorPrecedence) - 1 do begin 318 I := 1; 319 while (I < Length(Expression^.Items) - 1) do begin 320 if (TExpression(Expression^.Items[I]).NodeType = ntOperator) and 321 not TExpression(Expression^.Items[I]).Associated and 322 (TExpression(Expression^.Items[I]).OperatorType = OperatorPrecedence[II]) then 323 begin 324 if Expression^.Items[I].OperatorType = opNot then begin 325 Expression^.Items[I].Associated := True; 326 SetLength(Expression^.Items[I].Items, 1); 327 Expression^.Items[I].Items[0] := Expression^.Items[I + 1]; 328 DeleteExpressionItem(Expression, I + 1); 329 end else begin 330 Expression^.Items[I].Associated := True; 331 SetLength(Expression^.Items[I].Items, 2); 332 Expression^.Items[I].Items[1] := Expression^.Items[I - 1]; 333 Expression^.Items[I].Items[0] := Expression^.Items[I + 1]; 334 DeleteExpressionItem(Expression, I + 1); 335 DeleteExpressionItem(Expression, I - 1); 336 end; 337 end else Inc(I); 338 end; 339 end; 340 end; 341 end; 342 343 procedure AssignExpression(ExpDst, ExpSrc: PExpression); 344 var 345 I: Integer; 346 begin 347 ExpDst^.OperatorType := ExpSrc^.OperatorType; 348 ExpDst^.NodeType := ExpSrc^.NodeType; 349 ExpDst^.Associated := ExpSrc^.Associated; 350 ExpDst^.Value := ExpSrc^.Value; 351 SetLength(ExpDst^.Items, 1); //Length(ExpSrc^.Items)); 352 for I := 0 to Length(ExpDst^.Items) - 1 do 353 ExpDst^.Items[I] := ExpSrc^.Items[I]; 354 end; 355 356 function ParseGetValue(GetValue: PGetValue; NoExpression: Boolean = False): Boolean; 231 357 var 232 358 Variable: PVariable; … … 234 360 FunctionCall: TExecution; 235 361 Expression: TExpression; 236 begin 362 Value: TConstant; 363 begin 364 Result := True; 365 if not NoExpression and ParseExpression(@Expression) then begin 366 GetValue^.ReadType := rtExpression; 367 GetValue^.Expression := GetMem(SizeOf(TExpression)); 368 FillChar(GetValue^.Expression^, SizeOf(TExpression), 0); 369 GetValue^.Expression^ := Expression; 370 //AssignExpression(GetValue^.Expression, @Expression); 371 end else 237 372 if ParseVariable(Variable) then begin 373 GetValue^.ReadType := rtVariable; 238 374 GetValue^.Variable := Variable; 239 GetValue^.ReadType := rtVariable;240 375 end else 241 376 if ParseConstant(Constant) then begin 377 GetValue^.ReadType := rtConstant; 242 378 GetValue^.Constant := Constant; 243 GetValue^.ReadType := rtConstant; 379 end else 380 if ParseValue(@Value) then begin 381 GetValue^.ReadType := rtValue; 382 GetValue^.Value := Value; 244 383 end else 245 384 if ParseExecution(@FunctionCall) then begin 246 GetValue^.FunctionCall := GetMem(SizeOf(TExecution)); 385 GetValue^.ReadType := rtFunctionCall; 386 GetValue^.FunctionCall := GetMem(SizeOf(TFunctionCall)); 387 FillChar(GetValue^.FunctionCall^, SizeOf(TFunctionCall), 0); 247 388 GetValue^.FunctionCall^ := FunctionCall; 248 GetValue^.ReadType := rtFunctionCall; 249 end else 250 if ParseExpression(@Expression) then begin 251 GetValue^.Expression := GetMem(SizeOf(TExpression)); 252 GetValue^.Expression^ := Expression; 253 GetValue^.ReadType := rtExpression; 254 end else 255 ShowError('Expected value'); 256 end; 257 258 function ParseAssignment: Boolean; 389 end else 390 Result := False; 391 end; 392 393 function ParseAssignment(Assignment: PAssignment): Boolean; 259 394 var 260 395 Variable: PVariable; 261 Assignment: TAssignment;262 396 begin 263 397 if ParseVariable(Variable) then begin 264 398 Result := True; 265 Assignment .Destination := Variable;399 Assignment^.Destination := Variable; 266 400 Expect(':='); 267 ParseGetValue(@Assignment .Source);401 ParseGetValue(@Assignment^.Source); 268 402 end else begin 269 403 Result := False; … … 283 417 Func := MainProgram.Functions.GetByName(Next); 284 418 if Func <> nil then begin 419 Execution^.Func := Func; 285 420 SetLength(Execution^.Parameters.Items, Length(Func^.Parameters.Items)); 286 421 if Length(Func^.Parameters.Items) > 0 then begin … … 311 446 if ParseBeginEnd(@BeginEnd) then begin 312 447 Command^.BeginEnd := GetMem(SizeOf(TBeginEnd)); 448 FillChar(Command^.BeginEnd^, SizeOf(TBeginEnd), 0); 313 449 Command^.BeginEnd^ := BeginEnd; 314 450 Command^.CmdType := ctBeginEnd; 315 451 end else 316 if ParseAssignment then begin452 if ParseAssignment(@Assignment) then begin 317 453 Command^.Assignment := GetMem(SizeOf(TAssignment)); 454 FillChar(Command^.Assignment^, SizeOf(TAssignment), 0); 318 455 Command^.Assignment^ := Assignment; 319 456 Command^.CmdType := ctAssignment; … … 321 458 if ParseExecution(@Execution) then begin 322 459 Command^.Execution := GetMem(SizeOf(TExecution)); 460 FillChar(Command^.Execution^, SizeOf(TExecution), 0); 323 461 Command^.Execution^ := Execution; 324 462 Command^.CmdType := ctExecution; … … 326 464 if ParseIfThen(@IfThenElse) then begin 327 465 Command^.IfThenElse := GetMem(SizeOf(TIfThenElse)); 466 FillChar(Command^.IfThenElse^, SizeOf(TIfThenElse), 0); 328 467 Command^.IfThenElse^ := IfThenElse; 329 468 Command^.CmdType := ctIfThenElse; … … 331 470 if ParseWhileDo(@WhileDo) then begin 332 471 Command^.WhileDo := GetMem(SizeOf(TWhileDo)); 472 FillChar(Command^.WhileDo^, SizeOf(TWhileDo), 0); 333 473 Command^.WhileDo^ := WhileDo; 334 474 Command^.CmdType := ctWhileDo; … … 341 481 Result := True; 342 482 Expect('if'); 343 Parse Expression(@IfThenElse.Condition);483 ParseGetValue(@IfThenElse.Condition); 344 484 Expect('then'); 345 485 ParseCommand(@IfThenElse^.DoThen); … … 356 496 Result := True; 357 497 Expect('while'); 358 Parse Expression(@WhileDo.Condition);498 ParseGetValue(@WhileDo.Condition); 359 499 Expect('do'); 360 500 ParseCommand(@WhileDo^.Command); … … 391 531 begin 392 532 if CheckNext('(') then begin 533 Result := True; 393 534 Expect('('); 394 535 ParamName := ReadNext; … … 398 539 if ParamType <> nil then begin 399 540 Params^.Add(FunctionParameterCreate(ParamName, ParamType)); 541 FunctionContext^.Variables.Add(VariableCreate(ParamName, ParamType)); 400 542 end else ShowError('Unknown parameter type ' + ParamTypeName); 401 543 Expect(')'); 402 end ;544 end else Result := False; 403 545 end; 404 546 … … 424 566 VarType := MainProgram^.Types.GetByName(VarTypeName); 425 567 if VarType <> nil then begin 426 MainProgram^.Variables.Add(VariableCreate(VarName, VarType)); 568 if FunctionContext = nil then 569 MainProgram^.Variables.Add(VariableCreate(VarName, VarType)) 570 else FunctionContext^.Variables.Add(VariableCreate(VarName, VarType)); 427 571 end else ShowError('Unknown variable type ' + VarTypeName); 428 572 Expect(';'); … … 435 579 var 436 580 ReturnType: string; 581 DataType: PType; 437 582 begin 438 583 if CheckNext('function') then begin 439 584 Result := True; 440 585 Expect('function'); 586 FunctionContext := Func; 441 587 Func^.Name := ReadNext; 442 588 ParseParams(@Func^.Parameters); 443 589 Expect(':'); 444 590 ReturnType := ReadNext; 591 DataType := MainProgram.Types.GetByName(ReturnType); 592 if DataType <> nil then Func^.ReturnType := DataType 593 else ShowError('Unknown type ' + ReturnType); 445 594 Expect(';'); 595 Func^.Variables.Add(VariableCreate('Result', Func^.ReturnType)); 446 596 if ParseVariableSection then begin 447 597 end; 448 598 ParseBeginEnd(@Func^.BeginEnd); 599 FunctionContext := nil; 449 600 Expect(';'); 450 601 end else Result := False; … … 456 607 Result := True; 457 608 Expect('procedure'); 609 FunctionContext := Func; 458 610 Func^.Name := ReadNext; 459 611 ParseParams(@Func^.Parameters); … … 462 614 end; 463 615 ParseBeginEnd(@Func^.BeginEnd); 616 FunctionContext := nil; 464 617 Expect(';'); 465 618 end else Result := False; … … 491 644 492 645 SetLength(ProgramCode^.Variables.Items, 0); 493 ProgramCode^.Variables.Add(VariableCreate('Result', TypeString));494 ProgramCode^.Variables.Add(VariableCreate('C', TypeChar));495 ProgramCode^.Variables.Add(VariableCreate('Text', TypeString));496 646 497 647 SetLength(ProgramCode^.Functions.Items, 0); … … 527 677 repeat 528 678 SetLength(NewFunc.Parameters.Items, 0); 679 SetLength(NewFunc.Variables.Items, 0); 529 680 if ParseFunction(@NewFunc) then begin 530 681 ProgramCode.Functions.Add(NewFunc); … … 534 685 end else Break; 535 686 until False; 687 FunctionContext := nil; 536 688 ParseBeginEnd(@ProgramCode.BeginEnd); 537 689 Expect('.'); -
branches/interpreter/Source3.pas
r99 r100 15 15 PExecution = ^TExecution; 16 16 17 TOperator = (opNone, opAdd, opSubtract, opAnd, opOr, opNot, opEqual, opNotEqual); 18 17 19 TBaseType = (btBoolean, btInteger, btChar, btShortString, btArray); 18 20 … … 48 50 49 51 TConstant = record 50 Name: s tring;52 Name: shortstring; 51 53 DataType: PType; 52 54 Index: Integer; … … 85 87 TCommand = record 86 88 CmdType: TCmdType; 87 Ptr: Pointer;88 89 case Integer of 89 90 0: (WhileDo: PWhileDo); … … 103 104 end; 104 105 105 TReadType = (rtVariable, rtConstant, rtExpression, rtFunctionCall );106 TReadType = (rtVariable, rtConstant, rtExpression, rtFunctionCall, rtValue); 106 107 TGetValue = record 107 108 ReadType: TReadType; … … 111 112 rtExpression: (Expression: PExpression); 112 113 rtFunctionCall: (FunctionCall: PExecution); 114 rtValue: (Value: TConstant); 113 115 end; 114 116 PGetValue = ^TGetValue; 115 117 116 TExp Operand = (eoNone, eoAdd, eoSubtract, eoAnd, eoOr, eoNot);118 TExpNodeType = (ntNone, ntValue, ntOperator); 117 119 118 120 TExpression = record 119 Operand: TExpOperand; 120 Items: array of TGetValue; 121 NodeType: TExpNodeType; 122 OperatorType: TOperator; 123 Items: array of TExpression; 124 Value: TGetValue; 125 Parentheses: Boolean; 126 Associated: Boolean; 121 127 end; 122 128 … … 181 187 function FunctionParameterCreate(Name: string; DataType: PType): TFunctionParameter; 182 188 189 var 190 OperatorString: array[TOperator] of string = ('', '+', '-', 'and', 'or', 'not', 191 '=', '<>'); 192 193 const 194 OperatorPrecedence: array[0..6] of TOperator = (opNot, opAnd, opOr, opAdd, 195 opSubtract, opEqual, opNotEqual); 196 183 197 184 198 implementation -
branches/interpreter/project3.lpi
r96 r100 20 20 <StringTable ProductVersion=""/> 21 21 </VersionInfo> 22 <BuildModes Count="1"> 23 <Item1 Name="Default" Default="True"/> 22 <BuildModes Count="2"> 23 <Item1 Name="Debug" Default="True"/> 24 <Item2 Name="Release"> 25 <CompilerOptions> 26 <Version Value="11"/> 27 <Target> 28 <Filename Value="project3"/> 29 </Target> 30 <SearchPaths> 31 <IncludeFiles Value="$(ProjOutDir)"/> 32 <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> 33 </SearchPaths> 34 <Parsing> 35 <SyntaxOptions> 36 <SyntaxMode Value="Delphi"/> 37 <CStyleOperator Value="False"/> 38 <AllowLabel Value="False"/> 39 <CPPInline Value="False"/> 40 </SyntaxOptions> 41 </Parsing> 42 <Linking> 43 <Debugging> 44 <GenerateDebugInfo Value="False"/> 45 </Debugging> 46 </Linking> 47 </CompilerOptions> 48 </Item2> 24 49 </BuildModes> 25 50 <PublishOptions> … … 63 88 <SyntaxOptions> 64 89 <SyntaxMode Value="Delphi"/> 90 <CStyleOperator Value="False"/> 91 <IncludeAssertionCode Value="True"/> 92 <AllowLabel Value="False"/> 93 <CPPInline Value="False"/> 65 94 </SyntaxOptions> 66 95 </Parsing> 96 <CodeGeneration> 97 <Checks> 98 <IOChecks Value="True"/> 99 <RangeChecks Value="True"/> 100 <OverflowChecks Value="True"/> 101 <StackChecks Value="True"/> 102 </Checks> 103 <VerifyObjMethodCallValidity Value="True"/> 104 </CodeGeneration> 67 105 </CompilerOptions> 68 106 <Debugging>
Note:
See TracChangeset
for help on using the changeset viewer.