Possible bug?

New to FreeBASIC? Post your questions here.
StillLearning
Posts: 54
Joined: Aug 27, 2019 22:22

Possible bug?

Post by StillLearning »

Please look at the following short program fragment listed below:

Code: Select all

#lang "fblite"

sub GetFloatNumber(Number,TxtChar)

'Dim Digit as string
'Dim Number as Double
'Dim DotExists as Boolean
'Dim PlusExists as Boolean
'Dim MinusExists as Boolean

BuildNumber(Digit,DigitCount,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
IF (Digit = ".") or (DigitCount = 0) THEN
  print "error floating-point number expected"
end if
end sub 

GetFloatNumber(Number,TxtChar)
end

When I compile it I get two different errors:

Code: Select all

numtest.bas(11)  Error 71: Array not dimensioned before "(".
BuildNumber(Digit,DigitCount,TxtLine,_
            ^

numtest.bas(13)  Error 20: Type mismatch, found ")"
IF (Digit = ".") or (DigitCount = 0) THEN
               ^
For the first error message I am not using a array. So why is that error occurring?

What is wrong with the "IF" statement for the second instruction?


Can someone please help me determine what I am doing wrong.
BasicCoder2
Posts: 3917
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Possible bug?

Post by BasicCoder2 »

You have not defined BuildNumber as a SUB so it assumes it is an array.
It assumes Digit is a number and you are trying to assign a string.
StillLearning
Posts: 54
Joined: Aug 27, 2019 22:22

Re: Possible bug?

Post by StillLearning »

Thank you for your response. So do I always have to create the sub before I use it. I found I get the same error message if I place the actual definition of the sub after I use it. Is there a better method?

Thank you for your help.
BasicCoder2
Posts: 3917
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Possible bug?

Post by BasicCoder2 »

If you are going to use a sub or function it must be defined before it is called or you can declare it at the start.

Code: Select all

screenres 640,480,32

declare PrintColorText(txt as string, c as ulong)

printColorText("hello",rgb(255,0,0))

sub PrintColorText(txt as string,c as ulong)
    color c
    print txt;
end sub

sleep
StillLearning
Posts: 54
Joined: Aug 27, 2019 22:22

Re: Possible bug?

Post by StillLearning »

I made the changes you mentioned but I still get a error for DIGIT. I dimensioned it as a string but it still wants to use it as a integer.

Code: Select all

#lang "fblite"

sub BuildNumber(Digit,DigitCount,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
end sub

sub GetFloatNumber(Number,TxtChar)

Dim Digit as string
Dim Number as Double
Dim DotExists as Boolean
Dim PlusExists as Boolean
Dim MinusExists as Boolean

BuildNumber(Digit,DigitCount,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
IF (Digit = ".") or (DigitCount = 0) THEN
  print "error floating-point number expected"
end if
end sub 

GetFloatNumber(Number,TxtChar)
end
here is the error:

Code: Select all

numtest.bas(15)  Error 57: Type mismatch at parameter 1 (DIGIT) of BUILDNUMBER()
BuildNumber(Digit,DigitCount,TxtLine,_
                 ^
What am I doing wrong?
BasicCoder2
Posts: 3917
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Possible bug?

Post by BasicCoder2 »

Well you haven't made the changes I suggested in my example. You have to define the type in the parameter list.

sub BuildNumber(Digit as string, DigitCount as integer and so on...)

The Dim Digit as string in the GetFloatNumber() subroutine is not visible outside of that subroutine.

What is BuildNumber() supposed to do?
StillLearning
Posts: 54
Joined: Aug 27, 2019 22:22

Re: Possible bug?

Post by StillLearning »

Ok, I declared both of the subroutines. But now I am getting 4 different errors all of them are type mismatch. This routine when I am done validates a floating point number.

I thought I understood how to pass a parameter. From the errors am I getting I guess I don't.

Here is my new code :

Code: Select all

#lang "fblite"

Declare sub BuildNumber(Digit as String,DigitCount as Ubyte,TxtLine as String,_
                        TxtPos as short,TxtChar as string ,DotExists as boolean,_
                        PlusExists as boolean,MinusExists as boolean)
Declare sub GetFloatNumber(Number as Double,TxtChar as string)

sub GetFloatNumber(Number,TxtChar)

Dim Digit as string
Dim DigitCount as Ubyte
Dim DotExists as Boolean
Dim PlusExists as Boolean
Dim MinusExists as Boolean

BuildNumber(Digit,DigitCount,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
IF (Digit = ".") or (DigitCount = 0) THEN
  print "error floating-point number expected"
end if
end sub 

sub BuildNumber(Digit,DigitCount,TxtLine,TxtPos,TxtChar,DotExists,_
                PlusExists,MinusExists)

end sub

GetFloatNumber(Number,TxtChar)
end
Here are the error messages:

Code: Select all

numtest.bas(8) error 57: Type mismatch,  at parameter 1 (Number) of GetFloatNumber()
GetFloatNumber(Number,TxtChar)
                             ^
numtest.bas(16) error 57: Type mismatch,  at parameter 3 BUILDNUMBER()
BuildNumber(Digit,DigitCount,TxtLine,_
                                    ^
numtest.bas(24) error 57: Type mismatch,  at parameter 1 (Digit) of BuildNumber()
                PlusExists,MinusExists)
                                      *
numtest.bas(28) error 57: Type mismatch,  at parameter 1 (Number) of GETFLOATNUMBER()
GetFloatNumber(Number,TxtChar)
                     ^                                         

badidea
Posts: 2594
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Possible bug?

Post by badidea »

StillLearning wrote:I made the changes you mentioned but I still get a error for DIGIT. I dimensioned it as a string but it still wants to use it as a integer.
The quick (and dirty) fix requires only 4 characters: "$" and 3 x " ' ":

Code: Select all

#lang "fblite"

sub BuildNumber(Digit$,DigitCount,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
end sub

sub GetFloatNumber(Number,TxtChar)

Dim Digit as string
Dim Number as Double
'Dim DotExists as Boolean
'Dim PlusExists as Boolean
'Dim MinusExists as Boolean

BuildNumber(Digit,DigitCount,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
IF (Digit = ".") or (DigitCount = 0) THEN
  print "error floating-point number expected"
end if
end sub

GetFloatNumber(Number,TxtChar)
end
For the version with all variables defined with type:

Code: Select all

#lang "fblite"

sub BuildNumber(Digit as String,DigitCount as Ubyte,TxtLine as String,_
                TxtPos as short,TxtChar as string ,DotExists as boolean,_
                PlusExists as boolean,MinusExists as boolean)
end sub

sub GetFloatNumber(Number as double,TxtChar as string)
	
	Dim as string Digit,TxtLine
	Dim as short TxtPos
	Dim as Ubyte DigitCount
	Dim as Boolean DotExists, PlusExists, MinusExists

	BuildNumber(Digit,DigitCount,TxtLine,_
				TxtPos,TxtChar,DotExists,_
				PlusExists,MinusExists)
	IF (Digit = ".") or (DigitCount = 0) THEN
	  print "error floating-point number expected"
	end if
end sub

Dim as double Number
Dim as string TxtChar

GetFloatNumber(Number,TxtChar)
end
Here I put sub BuildNumber before sub GetFloatNumber so that the declares are not needed.
Note that #lang "fblite" can now be removed.
paul doe
Moderator
Posts: 1740
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Possible bug?

Post by paul doe »

StillLearning wrote:...
I thought I understood how to pass a parameter. From the errors am I getting I guess I don't.
...
Here's your code, modified so that it actually compiles:

Code: Select all

'#lang "fblite" <-- Forget this directive and pretend it was all a bad dream

sub _
  BuildNumber( _
    byref Digit as string, _
    byval DigitCount as ubyte, _
    byref TxtLine as string,_
    byval TxtPos as short, _
    byref TxtChar as string, _
    byval DotExists as boolean,_
    byval PlusExists as boolean, _
    byval MinusExists as boolean )
  
  '' Sub here
end sub

sub GetFloatNumber( _
  byval Number as double, _
  byref TxtChar as string )

  Dim Digit as string
  Dim DigitCount as Ubyte
  Dim DotExists as Boolean
  Dim PlusExists as Boolean
  Dim MinusExists as Boolean
  dim TxtLine as string
  dim TxtPos as short
  
  BuildNumber( _
    Digit,DigitCount,TxtLine, _
    TxtPos,TxtChar,DotExists,PlusExists,MinusExists )
  
  IF (Digit = ".") or (DigitCount = 0) THEN
    print "error floating-point number expected"
  end if
end sub

'' Pass something to parameters, their names are just 'placeholders'
dim as double _
  number => 0.0
dim as string _
  TxtChar => "123.12"

GetFloatNumber( Number, TxtChar )

'end <-- Not needed unless you want to return a value to the OS

sleep()
You can't reference anything that's not declared, defined, or dimensioned in FreeBasic. Function parameters don't exist on their own, they're just placeholders for values or variables (you have to replace them in the function call for something; FreeBasic doesn't support named parameters)

What is the purpose of this code? To check if a given string is a floating-point number? Is it part of a lexer (ie a recognizer)?
StillLearning
Posts: 54
Joined: Aug 27, 2019 22:22

Re: Possible bug?

Post by StillLearning »

I changed to your method, with the byref and byval. Here is the code:

Code: Select all

sub BuildNumber(_
  Byref Digit as string,_
  byval DigitCount as Ubyte,_
  byval SignificantDigits as ubyte,_
  Byref TxtLine as string,_
  byval TxtPos as short,_
  Byref TxtChar as string,_
  byval DotExists as boolean,_
  byval PlusExists as boolean,_
  byval MinusExists as boolean)

end sub

sub GetFloatNumber(_
  byval Number as Double,_
  byref TxtChar as string,_
  byval TxtPos as short,_
  byref TxtLine as string,_
  byval IsFloat as boolean,_
  byval DataSize as ubyte)

Dim Digit as string
Dim DigitCount as Ubyte
Dim SignificantDigits as uByte
Dim DotExists as Boolean
Dim PlusExists as Boolean
Dim MinusExists as Boolean

BuildNumber(Digit,DigitCount,SignificantDigits,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
IF (Digit = ".") or (DigitCount = 0) THEN
  print "error floating-point number expected"
end if
end sub 

Dim TxtLine as string
Dim DataSize as ubyte
dim IsFloat as boolean

DataSize = 4
IsFloat = True
Still have same problem with using subroutines.

Code: Select all

numtest.bas(46) error 41: Variable not declared, Number in
'GetFloatNumber(Number,TxtChar,TxtPos,TxtLine,IsFloat,DataSize)'
Number in the subroutine is already declared to be double.
Having lots of problems getting FREEBASIC to compile subroutines.
What do I have wrong???

I am working on creating a completely interactive incremental MASM assembler. This will be part of the code needed to assemble "REAL4", "REAL8" and 'REAL10" data instructions.
BasicCoder2
Posts: 3917
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Possible bug?

Post by BasicCoder2 »

You don't define a variable in the sub's parameter list. The variable Number in the parameter list is only visible within the subroutine.

Code: Select all

sub BuildNumber(_
  Byref Digit as string,_
  byval DigitCount as Ubyte,_
  byval SignificantDigits as ubyte,_
  Byref TxtLine as string,_
  byval TxtPos as short,_
  Byref TxtChar as string,_
  byval DotExists as boolean,_
  byval PlusExists as boolean,_
  byval MinusExists as boolean)

end sub

sub GetFloatNumber(_
  byval Number as Double,_
  byref TxtChar as string,_
  byval TxtPos as short,_
  byref TxtLine as string,_
  byval IsFloat as boolean,_
  byval DataSize as ubyte)

Dim Digit as string
Dim DigitCount as Ubyte
Dim SignificantDigits as uByte
Dim DotExists as Boolean
Dim PlusExists as Boolean
Dim MinusExists as Boolean

BuildNumber(Digit,DigitCount,SignificantDigits,TxtLine,_
            TxtPos,TxtChar,DotExists,PlusExists,MinusExists)
IF (Digit = ".") or (DigitCount = 0) THEN
  print "error floating-point number expected"
end if
end sub

'variables for main program defined here
Dim TxtLine as string
Dim DataSize as ubyte
dim IsFloat as boolean
dim Number as Double
dim TxtChar as string
dim TxtPos as short

DataSize = 4
IsFloat = True

GetFloatNumber(Number,TxtChar,TxtPos,TxtLine,IsFloat,DataSize)
Last edited by BasicCoder2 on Feb 04, 2020 7:18, edited 8 times in total.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Possible bug?

Post by MrSwiss »

Well, as I see it currently, there are "the bones" of the Sub(routines) but, "the meat" is missing.
What that means is, you don't "do" anything within the sub's body (there is nothing).

If you want to return something (typically a result) you should consider a Function, instead of Sub.

Code: Select all

Declare Function CalcDbl(ByVal As Double, ByVal As Double, ByVal As UByte) As Double

' ----- Demo -----
Print CalcDbl(1.25, 7.3333, Asc("+"))
Print CalcDbl(1.25, 7.3333, Asc("-"))
Print CalcDbl(1.25, 7.3333, Asc("/"))
Print CalcDbl(1.25, 7.3333, Asc("*"))
?
Sleep
' ----- end Demo -----

' implementations ...
Function CalcDbl( _                     ' calculate w. Double's
    ByVal v1    As Double, _            ' _in_ first value
    ByVal v2    As Double, _            ' _in_ second value
    ByVal op    As UByte   _            ' _in_ operand
    ) As Double Export                  ' _out_ result
    Select Case As Const op
        Case Asc("+") : Return v1 + v2
        Case Asc("-") : Return v1 - v2
        Case Asc("*") : Return v1 * v2
        Case Asc("/")                   ' division by NULL check needed
            If v2 = 0.0 Then
                Print "ERROR: division by NULL attempt!"
                Exit Function
            End If
            Return v1 / v2              ' use float division
        Case Else                       ' inforn user: unknown operand
            Print "ERROR: unknown operand!"
            Exit Function
    End Select
End Function
'----- EOF -----
The Export specifier isn't really needed here, only for DLL/SO use, where I took the Function from.
StillLearning
Posts: 54
Joined: Aug 27, 2019 22:22

Re: Possible bug?

Post by StillLearning »

Thank you all for your help in this matter. This is what I have learned about subroutines and functions.:
A variable name MUST first have a "DIM" created before it can used if it is one of the parameters being passed to/from a subroutine or function as well as you must use byval or byref in the subroutine or function being defined that uses that variable name as one of its parameters.

But I am pretty sure I have found a couple of "bugs" in the freebasic compiler:
First bug:

Code: Select all

  Dim Number as Double
  Dim MinNumber as Double
  Dim MaxNumber as Double 
  
  Number = 1.23
  MinNumber = 1.1754944E-38
  MaxNumber = 3.4028235E+38 
  
  if (Number < MinNumber) or (Number > MaxNumber) then
    print "Error floating-point number too small or too big"
  end if
  'This causes a error in the compiler
  if (Number <= MinNumber) or (Number => MaxNumber) then
    print "Error floating-point number too small or too big"
  end if
 sleep() 
The error message is:

Code: Select all

numtest.bas(13) error 7: Expected ')' , found  '=>'
in 'if (Number <= MinNumber) or (Number => MaxNumber) then'
Second bug:

Code: Select all

Dim TxtChar as string

If (TxtChar =>"a") and (TxtChar<="z") then
  Print TxtChar
end if
sleep()
The error message is:

Code: Select all

numtest.bas(3) error 7: Expected ')' , found  '=>'
in 'If (TxtChar => "a") and (TxtChar <= "z") then'
Is this comparison not allowed in FreeBasic? I know it works in QuickBasic and in dos basic.
fxm
Moderator
Posts: 12159
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Possible bug?

Post by fxm »

For both cases:
Don't confuse '=>' with '>='.
('=>' is the assignment operator as '=', while '>=' is the comparison operator)
StillLearning
Posts: 54
Joined: Aug 27, 2019 22:22

Re: Possible bug?

Post by StillLearning »

Thank you fxm. I did not know that it was different between the basic languages.
Post Reply