-1

I'm new to Lazarus and today I faced an issue with if-else usage. Everything is ok while there is only an if statement but when I'm trying to write an if-else statement this error shows up:

unit1.pas(48, 3) Fatal: Syntax error, ";" expected but "Else" found

I'm not sure if I need to wrap code inside the statements with begin end, but this FreePascal wiki page shows it like this

My code:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Math;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  a, b, c, d, x, x1, x2:real;
begin
  a := strToFloat(Edit1.Text);
  b := strToFloat(Edit2.Text);
  c := strToFloat(Edit3.Text);
  d := Power(b, 2) - 4 * a * c;
  if d > 0 then
    x1 := (-b + sqrt(d))/(2 * a);
    x2 := (-b - sqrt(d))/(2 * a);
    Label1.Caption := 'x1 = ' + floatToStr(x1) + #10 + 'x2 = ' + floaTToStr(x2)
  else
    if d < 0 then
      Label1.Caption := 'Розв*язків немає';
    else
      x1 := (-b + sqrt(d))/(2 * a);
      Label1.Caption := 'x = ' + floatToStr(x);
end.
comav
  • 63
  • 1
  • 4
  • If you look a the page you link to, you find this example: `if BooleanExpression then StatementIfTrue else StatementIfFalse;` at the top. Immediately below this example, there is a note: "Note there is never a semicolon ; immediately before the else." Also, the compiler error is fairly clear, isn't it? – Andreas Rejbrand Apr 25 '22 at 09:11
  • Pascal has never allowed a semicolon before an else, i.e. you need to remove it from: `Label1.Caption := 'Розв*язків немає';` – Dave Nottage Apr 25 '22 at 09:12
  • 2
    Also note, I thought that if there were more than 1 line in an ```if``` condition or the ```else``` condition, you need to enclose them between ```begin ... end``` – ewokx Apr 25 '22 at 09:13
  • Also, if you need more than a single statement to belong to a branch, you must use `begin..end` blocks. So in your code above, the `if d > 0 then` only applies to `x1 := (-b + sqrt(d))/(2 * a);` and not to the two next lines. You need to put these three lines within a `begin..end` block, so that this entire block will belong to the `if d > 0 then`. And, of course, no semicolon on this block's `end`, because there is an `else` after it! – Andreas Rejbrand Apr 25 '22 at 09:13
  • @ewong: There can be any number of lines without any need for a `begin..end` block. But there can only be a single *statement*. – Andreas Rejbrand Apr 25 '22 at 09:14
  • Perhaps the poster compares the indented statements in Python with pascal. From indentation it *looks* correct, but as others have pointed out, having multiple statements under the `if ... ` requires `if (this) then begin {statements here ... } end` – MyICQ Apr 25 '22 at 09:29
  • 2
    Indeed, in Delphi (and most other programming languages except Python), whitespace in general and indentation in particular is ignored (\*); the compiler doesn't care about the indentation. So as far as the compiler is concerned, the program is exactly the same if you remove the leading whitespace from every line. [\* Nitpick: Of course whitespace is used to delimit tokens and is very much preserved in string literals.] – Andreas Rejbrand Apr 25 '22 at 09:33

1 Answers1

1

You seem to be trying to use indentation to group code under statements. Pascal doesn't use indentation for nesting code (I'm honestly unsure what its called). You need to use begin and then afterwards end.

Meaning you code should look as follows:

  if d > 0 then
  begin
    // All 3 lines below will run if "d > 0"
    x1 := (-b + sqrt(d)) / (2 * a);
    x2 := (-b - sqrt(d)) / (2 * a);
    Label1.Caption := 'x1 = ' + floatToStr(x1) + #10 + 'x2 = ' + floatToStr(x2);
  end // Do not ";" since the if statement is not over yet
  else if d < 0 then
  begin
    Label1.Caption := 'Розв*язків немає';
  end // Do not ";" since the if statement is not over yet
  else
  begin
    x1 := (-b + sqrt(d)) / (2 * a);
    Label1.Caption := 'x = ' + floatToStr(x);
  end; // End of the if statment
Adriaan
  • 806
  • 7
  • 24
  • 2
    imo, it would be better to not have a begin..end block for d < 0, to illustrate how code should look when it is not needed – RaelB Apr 25 '22 at 14:03
  • I agree with you @RaelB . I did it like this because OP doesn't seem to be familiar with pascal at all so this would be simpler. Also I didn't know how to properly explain it in English so that it would make sense for beginners like OP – Adriaan Apr 26 '22 at 11:02