From 9b04508ec74122155c5c0f9b0da04ecb9e70246b Mon Sep 17 00:00:00 2001 From: coderJeff Date: Thu, 28 Jun 2018 22:55:51 -0400 Subject: [PATCH 1/7] fbdoc: wiki snapshot 2018-06-28 --- doc/manual/cache/CatPgStdDataTypes.wakka | 8 ++ doc/manual/cache/CatPgUserDefTypes.wakka | 108 +++++++++++++++-------- doc/manual/cache/CatPgVariables.wakka | 14 +-- doc/manual/cache/KeyPgFunctionPtr.wakka | 44 +++++++++ doc/manual/cache/KeyPgSubPtr.wakka | 51 +++++++++++ 5 files changed, 181 insertions(+), 44 deletions(-) create mode 100644 doc/manual/cache/KeyPgFunctionPtr.wakka create mode 100644 doc/manual/cache/KeyPgSubPtr.wakka diff --git a/doc/manual/cache/CatPgStdDataTypes.wakka b/doc/manual/cache/CatPgStdDataTypes.wakka index 2f3aa47ea2..5de49ef1c4 100644 --- a/doc/manual/cache/CatPgStdDataTypes.wakka +++ b/doc/manual/cache/CatPgStdDataTypes.wakka @@ -7,6 +7,8 @@ Built-in data types Types that store real number values, whose range and precision is determined by the size of the data type. **{{anchor name="BOOLEAN|Boolean types"}}** Types that store boolean values. +**{{anchor name="PROCTYPES|Procedure Types"}}** + Types that store pointers to procedures **{{anchor name="MODIFIERS|Data Type Modifiers"}}** Specifies additional characteristics of a standard or user-defined data type. **{{anchor name="STRING|String types"}}** @@ -35,6 +37,12 @@ Built-in data types {{anchor name="BOOLEAN"}}{{fbdoc item="section" value="Boolean types"}} =={{fbdoc item="keyword" value="KeyPgBoolean|BOOLEAN"}}== 1-bit wide data types that store boolean values. + +{{anchor name="PROCTYPES"}}{{fbdoc item="section" value="Procedure Types"}} + =={{fbdoc item="keyword" value="KeyPgFunctionPtr|FUNCTION Pointer"}}== + Types that store a pointer to a function procedure + =={{fbdoc item="keyword" value="KeyPgSubPtr|SUB Pointer"}}== + Types that store a pointer to a sub procedure <<>>{{anchor name="MODIFIERS"}}{{fbdoc item="section" value="Data Type Modifiers"}} =={{fbdoc item="keyword" value="KeyPgConstQualifier|CONST"}}== Specifies a read only type. diff --git a/doc/manual/cache/CatPgUserDefTypes.wakka b/doc/manual/cache/CatPgUserDefTypes.wakka index 2f02bee080..f8450137c8 100644 --- a/doc/manual/cache/CatPgUserDefTypes.wakka +++ b/doc/manual/cache/CatPgUserDefTypes.wakka @@ -1,45 +1,79 @@ {{fbdoc item="title" value="User Defined Types"}}---- -<<{{fbdoc item="section" value="Declaration"}} - - {{fbdoc item="keyword" value="KeyPgEnum|ENUM...END ENUM"}} - - {{fbdoc item="keyword" value="KeyPgType|TYPE...END TYPE"}} - - {{fbdoc item="keyword" value="KeyPgClass|CLASS...END CLASS"}} - - {{fbdoc item="keyword" value="KeyPgUnion|UNION...END UNION"}} - - {{fbdoc item="keyword" value="KeyPgExtends|EXTENDS"}} - - {{fbdoc item="keyword" value="KeyPgImplements|IMPLEMENTS"}} - - {{fbdoc item="keyword" value="KeyPgField|FIELD"}} - - {{fbdoc item="keyword" value="KeyPgObject|OBJECT"}} +**{{anchor name="DECLARATION|Declaration"}}** + Declaring and describing user defined types +**{{anchor name="REFERENCING|Referencing"}}** + Accessing data in a user defined type +**{{anchor name="MEMBERPROC|Member Procedures"}}** + Declaring and defining methods related to a user defined type +**{{anchor name="MEMBERACCESS|Member Access Control"}}** + Controlling when data and member procedures are accessed -{{fbdoc item="section" value="Referencing"}} - - {{fbdoc item="keyword" value="KeyPgTypeTemp|Temporary Types"}} - - {{fbdoc item="keyword" value="KeyPgThis|THIS"}} - - {{fbdoc item="keyword" value="KeyPgBase|BASE (member access)"}} - - {{fbdoc item="keyword" value="KeyPgTypeAlias|Type Alias"}} - - {{fbdoc item="keyword" value="KeyPgWith|WITH"}} -<<>>{{fbdoc item="section" value="Member Procedures"}} - - {{fbdoc item="keyword" value="KeyPgBaseInit|BASE (initialization)"}} - - {{fbdoc item="keyword" value="KeyPgConstructor|CONSTRUCTOR"}} - - {{fbdoc item="keyword" value="KeyPgDestructor|DESTRUCTOR"}} - - {{fbdoc item="keyword" value="KeyPgMemberFunction|FUNCTION"}} - - {{fbdoc item="keyword" value="KeyPgOperator|OPERATOR"}} - - {{fbdoc item="keyword" value="KeyPgOverride|OVERRIDE"}} - - {{fbdoc item="keyword" value="KeyPgProperty|PROPERTY"}} - - {{fbdoc item="keyword" value="KeyPgMemberSub|SUB"}} - - {{fbdoc item="keyword" value="KeyPgStaticMember|STATIC (Member)"}} - - {{fbdoc item="keyword" value="KeyPgVirtual|VIRTUAL"}} - - {{fbdoc item="keyword" value="KeyPgAbstract|ABSTRACT"}} - - {{fbdoc item="keyword" value="KeyPgConstMember|CONST (Member)"}} +<<{{anchor name="DECLARATION"}}{{fbdoc item="section" value="Declarations"}} + =={{fbdoc item="keyword" value="KeyPgEnum|ENUM...END ENUM"}}== + User defined enumeration of values + =={{fbdoc item="keyword" value="KeyPgType|TYPE...END TYPE"}}== + User defined structure of non overlapping data and member procedures + =={{fbdoc item="keyword" value="KeyPgClass|CLASS...END CLASS"}}== + Not implemented. Keyword reserved. + =={{fbdoc item="keyword" value="KeyPgUnion|UNION...END UNION"}}== + User defined structure of overlapping data + =={{fbdoc item="keyword" value="KeyPgExtends|EXTENDS"}}== + Extends an user defined type to derive another + =={{fbdoc item="keyword" value="KeyPgImplements|IMPLEMENTS"}}== + Not implemented. Keyword reserved. + =={{fbdoc item="keyword" value="KeyPgField|FIELD"}}== + Specifies field alignment within a user defined type + =={{fbdoc item="keyword" value="KeyPgObject|OBJECT"}}== + Built-in type providing run-time type information -{{fbdoc item="section" value="Member Access Control"}} - - {{fbdoc item="keyword" value="KeyPgVisPublic|PUBLIC: (Access Control)"}} - - {{fbdoc item="keyword" value="KeyPgVisPrivate|PRIVATE: (Access Control)"}} - - {{fbdoc item="keyword" value="KeyPgVisProtected|PROTECTED: (Access Control)"}} +{{anchor name="REFERENCING"}}{{fbdoc item="section" value="Referencing"}} + =={{fbdoc item="keyword" value="KeyPgTypeTemp|Temporary Types"}}== + Creates a temporary copy of a user defined type + =={{fbdoc item="keyword" value="KeyPgThis|THIS"}}== + Built-in, hidden, parameter passed to non-static member procedures to access the user defined type instance + =={{fbdoc item="keyword" value="KeyPgBase|BASE (member access)"}}== + Built-in, hidden, variable to access the base user defined type instance in derived user defined types + =={{fbdoc item="keyword" value="KeyPgTypeAlias|Type Alias"}}== + Declares a user defined type from other user defined or standard data types + =={{fbdoc item="keyword" value="KeyPgWith|WITH"}}== + Compound statement to access the data and members of a user defined type + +<<>>{{anchor name="MEMBERPROC"}}{{fbdoc item="section" value="Member Procedures"}} + =={{fbdoc item="keyword" value="KeyPgBaseInit|BASE (initialization)"}}== + Specifies an initializer for the base user defined type in derived user defined type constructors + =={{fbdoc item="keyword" value="KeyPgConstructor|CONSTRUCTOR"}}== + Declares or defines a member procedure that is automatically called when a user defined type is created + =={{fbdoc item="keyword" value="KeyPgDestructor|DESTRUCTOR"}}== + Declares or defines a member procedure that is automatically called when a user defined type is destroyed or goes out of scope + =={{fbdoc item="keyword" value="KeyPgMemberFunction|FUNCTION"}}== + Declares or defines a member procedure returning a value + =={{fbdoc item="keyword" value="KeyPgOperator|OPERATOR"}}== + Declares or defines an overloaded operator + =={{fbdoc item="keyword" value="KeyPgOverride|OVERRIDE"}}== + Member method attribute that specifies that the method is expected to override a virtual method in the base user defined type + =={{fbdoc item="keyword" value="KeyPgProperty|PROPERTY"}}== + Declares or defines property member procedures for a user defined type + =={{fbdoc item="keyword" value="KeyPgMemberSub|SUB"}}== + Declare or defines a member procedure + =={{fbdoc item="keyword" value="KeyPgStaticMember|STATIC (Member)"}}== + Declares or defines a member procedure or variable is static + =={{fbdoc item="keyword" value="KeyPgVirtual|VIRTUAL"}}== + Member method attribute that declares that a member must have an implementation + =={{fbdoc item="keyword" value="KeyPgAbstract|ABSTRACT"}}== + Member method attribute that declares that a member must be implemented in a derived user defined type + =={{fbdoc item="keyword" value="KeyPgConstMember|CONST (Member)"}}== + Member method attribute that declares or defines that the method is readonly and does not modify the user defined types's data + +{{anchor name="MEMBERACCESS"}}{{fbdoc item="section" value="Member Access Control"}} + =={{fbdoc item="keyword" value="KeyPgVisPublic|PUBLIC: (Access Control)"}}== + Data and members in a user defined type have public visibility + =={{fbdoc item="keyword" value="KeyPgVisPrivate|PRIVATE: (Access Control)"}}== + Data and members in a user defined type have private visibility + =={{fbdoc item="keyword" value="KeyPgVisProtected|PROTECTED: (Access Control)"}}== + Data and members in a user defined type have protected visibility >> ::c:: -{{fbdoc item="back" value="DocToc|Table of Contents"}} - - - - +{{fbdoc item="back" value="DocToc|Table of Contents"}} \ No newline at end of file diff --git a/doc/manual/cache/CatPgVariables.wakka b/doc/manual/cache/CatPgVariables.wakka index 14953af6ce..a8335ab481 100644 --- a/doc/manual/cache/CatPgVariables.wakka +++ b/doc/manual/cache/CatPgVariables.wakka @@ -1,19 +1,19 @@ {{fbdoc item="title" value="Variable Declarations"}}---- Statements to declare and allocate space for variables. -<<**{{fbdoc item="keyword" value="KeyPgDim|DIM"}}** +<<=={{fbdoc item="keyword" value="KeyPgDim|DIM"}}== Declares a variable at the current scope. -**{{fbdoc item="keyword" value="KeyPgConst|CONST"}}** +=={{fbdoc item="keyword" value="KeyPgConst|CONST"}}== Declares a non-modifiable variable. -**{{fbdoc item="keyword" value="KeyPgScope|SCOPE"}}** +=={{fbdoc item="keyword" value="KeyPgScope|SCOPE"}}== Begins a new scope block. -**{{fbdoc item="keyword" value="KeyPgStatic|STATIC"}}** +=={{fbdoc item="keyword" value="KeyPgStatic|STATIC"}}== Declares variables in a procedure that retain their value between calls. -<<>>**{{fbdoc item="keyword" value="KeyPgShared|SHARED"}}** +<<>>=={{fbdoc item="keyword" value="KeyPgShared|SHARED"}}== Used with ##[[KeyPgDim|Dim]]## allows variables to be visible throughout a module. -**{{fbdoc item="keyword" value="KeyPgVar|VAR"}}** +=={{fbdoc item="keyword" value="KeyPgVar|VAR"}}== Declares variables where the data type is implied from an initializer. -**{{fbdoc item="keyword" value="KeyPgByrefVariables|BYREF (variables)"}}** +=={{fbdoc item="keyword" value="KeyPgByrefVariables|BYREF (variables)"}}== Used with ##[[KeyPgDim|Dim]]## or ##[[KeyPgStatic|Static]]## or ##[[KeyPgVar|Var]]## allows to declare references. >> diff --git a/doc/manual/cache/KeyPgFunctionPtr.wakka b/doc/manual/cache/KeyPgFunctionPtr.wakka new file mode 100644 index 0000000000..3d3fc2c5ba --- /dev/null +++ b/doc/manual/cache/KeyPgFunctionPtr.wakka @@ -0,0 +1,44 @@ +{{fbdoc item="title" value="FUNCTION Pointer"}}---- +Data type that stores a pointer to a ##[[KeyPgFunction|FUNCTION]]## procedure returning a value + +{{fbdoc item="syntax"}}## + [[KeyPgDim|dim]] //variable// [[KeyPgAs|as]] [[KeyPgFunction|Function]] [[[KeyPgCdecl|CDecl]]|[[KeyPgPascal|Pascal]]|[[KeyPgStdcall|StdCall]]] [( [//parameter_list//] )] [ [[KeyPgByrefFunction|ByRef]] ] [[[KeyPgAs|As]] //return_type//] [= //initializer//] +## +{{fbdoc item="param"}} + ##//parameter_list//##: parameter[, parameter[, ...]] + ##//parameter//##: ##[[[KeyPgByref|ByRef]]|[[KeyPgByval|ByVal]]] //identifier// [[[KeyPgAs|As]] //type//] [= //default_value//]## + ##//identifier//##: the name of the variable referenced in the subroutine + ##//type//##: the type of variable + ##//default_value//##: the value of the argument if none is specified in the call + ##//return_value//##: the value returned from the function + ##//intializer//##: address of a subroutine to set as the intial value + +{{fbdoc item="desc"}} + A ##[[KeyPgFunction|Function]]## pointer is a procedure pointer that stores the memory location of compiled code that returns a value. If no intializer is given the default initial value is zero (0). + + The memory address for the ##[[KeyPgFunction|Function]]## procedure can be assigned to the variable by taking the address of a subroutine with ##[[KeyPgOpProcPtr|ProcPtr]]## or ##[[KeyPgOpAt|Operator @ (Address of)]]##. + + The procedure must match the same ##[[KeyPgFunction|Function]]## declaration as the declared ##[[KeyPgFunction|Function]]## pointer. + + To call the subroutine assigned, use the ##//variable//## name as if it were a normal declared ##[[KeyPgFunction|Function]]##. + +{{fbdoc item="ex"}} +{{fbdoc item="filename" value="examples/manual/datatype/funcptr.bas"}}%%(freebasic) +function ConcatSelf( x as string ) as string + return x & x +end function + +dim x as Function( x as string ) as string = procptr( ConcatSelf ) + +print x( "Hello" ) +%% + +{{fbdoc item="diff"}} + - New to ""FreeBASIC"" + +{{fbdoc item="see"}} + - ##[[KeyPgSub|Sub]]## + - ##[[KeyPgOpProcPtr|ProcPtr]]## + - ##[[KeyPgOpAt|Operator @ (Address of)]]## + +{{fbdoc item="back" value="CatPgStdDataTypes|Standard Data Types"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgSubPtr.wakka b/doc/manual/cache/KeyPgSubPtr.wakka new file mode 100644 index 0000000000..71c2ed1789 --- /dev/null +++ b/doc/manual/cache/KeyPgSubPtr.wakka @@ -0,0 +1,51 @@ +{{fbdoc item="title" value="SUB Pointer"}}---- +Data type that stores a pointer to a ##[[KeyPgSub|SUB]]## procedure + +{{fbdoc item="syntax"}}## + [[KeyPgDim|dim]] //variable// [[KeyPgAs|as]] [[KeyPgSub|Sub]] [[[KeyPgCdecl|CDecl]]|[[KeyPgPascal|Pascal]]|[[KeyPgStdcall|StdCall]]] [( [//parameter_list//] )] [= //initializer//] +## +{{fbdoc item="param"}} + ##//parameter_list//##: parameter[, parameter[, ...]] + ##//parameter//##: ##[[[KeyPgByref|ByRef]]|[[KeyPgByval|ByVal]]] //identifier// [[[KeyPgAs|As]] //type//] [= //default_value//]## + ##//identifier//##: the name of the variable referenced in the subroutine + ##//type//##: the type of variable + ##//default_value//##: the value of the argument if none is specified in the call + ##//intializer//##: address of a subroutine to set as the intial value + +{{fbdoc item="desc"}} + A ##[[KeyPgSub|Sub]]## pointer is a procedure pointer that stores the memory location of compiled code. If no intializer is given the default initial value is zero (0). + + The memory address for the ##[[KeyPgSub|Sub]]## procedure can be assigned to the variable by taking the address of a subroutine with ##[[KeyPgOpProcPtr|ProcPtr]]## or ##[[KeyPgOpAt|Operator @ (Address of)]]##. + + The procedure must match the same ##[[KeyPgSub|Sub]]## declaration as the declared ##[[KeyPgSub|Sub]]## pointer. + + To call the subroutine assigned, use the ##//variable//## name as if it were a normal declared ##[[KeyPgSub|Sub]]##. + +{{fbdoc item="ex"}} +{{fbdoc item="filename" value="examples/manual/datatype/funcptr.bas"}}%%(freebasic) + sub Hello() + print "Hello" + end sub + + sub Goodbye() + print "Goodbye" + end sub + + dim x as Sub() = procptr( Hello ) + + x() + + x = @Goodbye '' or procptr(Goodbye) + + x() +%% + +{{fbdoc item="diff"}} + - New to ""FreeBASIC"" + +{{fbdoc item="see"}} + - ##[[KeyPgSub|Sub]]## + - ##[[KeyPgOpProcPtr|ProcPtr]]## + - ##[[KeyPgOpAt|Operator @ (Address of)]]## + +{{fbdoc item="back" value="CatPgStdDataTypes|Standard Data Types"}} From 9d4da3f5549f35ef1cdf5d740f1b5b389fe6055d Mon Sep 17 00:00:00 2001 From: coderJeff Date: Thu, 23 Aug 2018 13:02:14 -0400 Subject: [PATCH 2/7] fbdoc: wiki snapshot 2018-08-23 --- doc/manual/cache/CatPgMemory.wakka | 4 +- doc/manual/cache/GlossaryIndex.wakka | 2 +- doc/manual/cache/KeyPgBinary.wakka | 2 +- doc/manual/cache/KeyPgByref.wakka | 2 +- doc/manual/cache/KeyPgByrefFunction.wakka | 12 ++-- doc/manual/cache/KeyPgByval.wakka | 4 +- doc/manual/cache/KeyPgDraw.wakka | 2 + doc/manual/cache/KeyPgFunctionPtr.wakka | 61 +++++++++++++++++- doc/manual/cache/KeyPgReturn.wakka | 7 +- doc/manual/cache/KeyPgScreengraphics.wakka | 4 ++ doc/manual/cache/KeyPgSubPtr.wakka | 74 +++++++++++++++++++++- doc/manual/cache/ProPgArrays.wakka | 2 +- doc/manual/cache/TutPointers.wakka | 10 +-- doc/manual/cache/TutPointersData.wakka | 6 +- 14 files changed, 169 insertions(+), 23 deletions(-) diff --git a/doc/manual/cache/CatPgMemory.wakka b/doc/manual/cache/CatPgMemory.wakka index a6bc01a516..9dd8ff3562 100644 --- a/doc/manual/cache/CatPgMemory.wakka +++ b/doc/manual/cache/CatPgMemory.wakka @@ -28,7 +28,9 @@ Procedures that work with static and dynamic memory. =={{fbdoc item="keyword" value="KeyPgSwap|SWAP"}}== Exchange the contents of two variables. =={{fbdoc item="keyword" value="KeyPgSadd|SADD"}}== - Returns the address for the data in a string variable. + Returns the address for the data in a zstring variable. >>::c:: +{{fbdoc item="see"}} + - [[CatPgOpMemory|Memory Operators]] {{fbdoc item="back" value="DocToc|Table of Contents"}} \ No newline at end of file diff --git a/doc/manual/cache/GlossaryIndex.wakka b/doc/manual/cache/GlossaryIndex.wakka index e9fa8fb141..90e16bd060 100644 --- a/doc/manual/cache/GlossaryIndex.wakka +++ b/doc/manual/cache/GlossaryIndex.wakka @@ -124,7 +124,7 @@ Brief definitions and explanations for words and phrases used in the ""FreeBASIC A source code statement (or statements) that allocates space for data or code. For example, ##[[KeyPgSub|Sub]]## defines a procedure by allocating space for the program code it will contain. Some statements can be both a declaration and a definition. For example, ##[[KeyPgDim|Dim]]## both declares and defines a variable. **dereference** - The act of obtaining a value from memory at a given address. See ##[[KeyPgOpValueOf|Operator * (ValueOf)]]##, ##[[ProPgPointers|Pointers]]##. + The act of accessing (in read and in write) a variable stored at a given address. See ##[[KeyPgOpValueOf|Operator * (ValueOf)]]##, ##[[ProPgPointers|Pointers]]##. **descriptor** Refers to the internal data structure used by the compiler and runtime library for managing variable length strings and arrays. diff --git a/doc/manual/cache/KeyPgBinary.wakka b/doc/manual/cache/KeyPgBinary.wakka index 64b4642a1f..8c69cfb6cc 100644 --- a/doc/manual/cache/KeyPgBinary.wakka +++ b/doc/manual/cache/KeyPgBinary.wakka @@ -24,7 +24,7 @@ Specifies file or device to be opened for binary mode ##//filename//## must be a string expression resulting in a legal file name in the target OS, without wildcards. The file will be sought for in the present directory, unless a path is given. - ##//Access_type//## By default ##**Binary**## mode allows to both read and write the file, unless an ##[[KeyPgAccess|Access]]## type is specified, it mus be one of: + ##//Access_type//## By default ##**Binary**## mode allows to both read and write the file, unless an ##[[KeyPgAccess|Access]]## type is specified, it must be one of: - ##**Read**## - the file is opened for input only - ##**Write**## - the file is opened for output only - ##**Read Write**## - the file is opened for input and output (the default) diff --git a/doc/manual/cache/KeyPgByref.wakka b/doc/manual/cache/KeyPgByref.wakka index b6ab109e89..341e5dd04f 100644 --- a/doc/manual/cache/KeyPgByref.wakka +++ b/doc/manual/cache/KeyPgByref.wakka @@ -35,7 +35,7 @@ end %% {{fbdoc item="lang"}} - - In //[[CompilerOptlang|-lang fb]]// dialect, ##**Byval**## is the default parameter passing convention for all built-in types except ##[[KeyPgString|String]]## and user-defined ##[[KeyPgType|Type]]## which are passed ##[[KeyPgByref|Byref]]## by default. + - In //[[CompilerOptlang|-lang fb]]// dialect, ##[[KeyPgByval|Byval]]## is the default parameter passing convention for all built-in types except ##[[KeyPgString|String]]## and user-defined ##[[KeyPgType|Type]]## which are passed ##**Byref**## by default. The ##[[KeyPgZstring|Zstring]]## and ##[[KeyPgWstring|Wstring]]## built-in types are also passed ##**Byref**## by default, but passing ##[[KeyPgByval|Byval]]## is forbidden. Arrays are always passed ##**Byref**## and the use of the specifier ##**Byref**## or ##[[KeyPgByval|Byval]]## is forbidden. - In //[[CompilerOptlang|-lang qb]]// and //[[CompilerOptlang|-lang fblite]]// dialects, ##**Byref**## is the default parameter passing convention. {{fbdoc item="diff"}} diff --git a/doc/manual/cache/KeyPgByrefFunction.wakka b/doc/manual/cache/KeyPgByrefFunction.wakka index 4c5e0af50e..e8897eb320 100644 --- a/doc/manual/cache/KeyPgByrefFunction.wakka +++ b/doc/manual/cache/KeyPgByrefFunction.wakka @@ -49,18 +49,22 @@ Function f1( ) ByRef As String End Function Function f2( ByRef _s As String ) ByRef As String - '' This variable-length string will be returned by reference, no copy will be created. + '' This variable-length string will transit by reference (input and output), no copy will be created. Function = _s End Function s = "abcd" Print s -f1( ) &= "efgh" +f1( ) = f1( ) & "efgh" +Print s + +'' The enclosing parentheses are required here on the left-hand side. +( f2( s ) ) = f2( s ) & "ijkl" Print s -'' At time of writing, the enclosing parentheses are required here. -( f2( s ) ) &= "ijkl" +'' The enclosing parentheses are not required here on the left-hand side. +f2( s ) => f2( s ) & "mnop" Print s %% {{fbdoc item="filename" value="examples/manual/procs/byref-result3.bas"}}%%(freebasic) diff --git a/doc/manual/cache/KeyPgByval.wakka b/doc/manual/cache/KeyPgByval.wakka index eb0779826d..d6711d4203 100644 --- a/doc/manual/cache/KeyPgByval.wakka +++ b/doc/manual/cache/KeyPgByval.wakka @@ -39,8 +39,8 @@ End %% {{fbdoc item="lang"}} - - In the //[[CompilerOptlang|-lang fb]]// dialect, ##**Byval**## is the default parameter passing convention for all built-in types except ##[[KeyPgString|String]]## and user-defined ##[[KeyPgType|Type]]## which are passed ##[[KeyPgByref|Byref]]## by default. - - In //[[CompilerOptlang|-lang qb]]// and //[[CompilerOptlang|-lang fblite]]// dialects, ##**Byref**## is the default parameter passing convention. + - In the //[[CompilerOptlang|-lang fb]]// dialect, ##**Byval**## is the default parameter passing convention for all built-in types except ##[[KeyPgString|String]]## and user-defined ##[[KeyPgType|Type]]## which are passed ##[[KeyPgByref|Byref]]## by default. The ##[[KeyPgZstring|Zstring]]## and ##[[KeyPgWstring|Wstring]]## built-in types are also passed ##[[KeyPgByref|Byref]]## by default, but passing ##**Byval**## is forbidden. Arrays are always passed ##[[KeyPgByref|Byref]]## and the use of the specifier ##[[KeyPgByref|Byref]]## or ##**Byval**## is forbidden. + - In //[[CompilerOptlang|-lang qb]]// and //[[CompilerOptlang|-lang fblite]]// dialects, ##[[KeyPgByref|Byref]]## is the default parameter passing convention. {{fbdoc item="diff"}} - QB only used ##**Byval**## in declarations to non-Basic subroutines diff --git a/doc/manual/cache/KeyPgDraw.wakka b/doc/manual/cache/KeyPgDraw.wakka index 3e315da581..9f8d4d8607 100644 --- a/doc/manual/cache/KeyPgDraw.wakka +++ b/doc/manual/cache/KeyPgDraw.wakka @@ -19,6 +19,8 @@ Statement for sequenced pixel plotting Commands to set the color, size and angle will take affect all subsequent ##**Draw**## operations. +##**Draw**## respects the current clipping region as set by the ##[[KeyPgViewgraphics|View (Graphics)]]## statement, but its coordinates are not affected by the custom coordinates system. + {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/gfx/draw.bas"}}%%(freebasic) screen 13 diff --git a/doc/manual/cache/KeyPgFunctionPtr.wakka b/doc/manual/cache/KeyPgFunctionPtr.wakka index 3d3fc2c5ba..592fc4cddc 100644 --- a/doc/manual/cache/KeyPgFunctionPtr.wakka +++ b/doc/manual/cache/KeyPgFunctionPtr.wakka @@ -21,6 +21,8 @@ Data type that stores a pointer to a ##[[KeyPgFunction|FUNCTION]]## procedure re The procedure must match the same ##[[KeyPgFunction|Function]]## declaration as the declared ##[[KeyPgFunction|Function]]## pointer. To call the subroutine assigned, use the ##//variable//## name as if it were a normal declared ##[[KeyPgFunction|Function]]##. + + One of the primary uses for procedure pointers is to create callback procedures. A callback procedure is a procedure created in the user program that is called by another procedure either from the user own code space or from an external library. {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/datatype/funcptr.bas"}}%%(freebasic) @@ -32,7 +34,64 @@ dim x as Function( x as string ) as string = procptr( ConcatSelf ) print x( "Hello" ) %% - +{{fbdoc item="filename" value="examples/manual/datatype/funcptr2.bas"}}%%(freebasic) +Function x2 (Byval i As Integer) As Integer + Return i * 2 +End Function + +Function x3 (Byval i As Integer) As Integer + Return i * 3 +End Function + +Function operation (Byval i As Integer, Byval op As Function (Byval As Integer) As Integer) As Integer + Return op(i) +End Function + +Print operation(4, @x2) +Print operation(4, @x3) +%% +{{fbdoc item="filename" value="examples/manual/datatype/funcptr3.bas"}}%%(freebasic) +' Example of basic callback Function mechanism to implement a key pressed event: +' (the user callback Function address cannot be modified while the event thread is running) +' - An asynchronous thread tests the keyboard in a loop, and calls a user callback Function each time a key is pressed. +' - The callback Function address is passed to the thread. +' - The callback Function prints the character of the key pressed, +' but if the key pressed is it orders the thread to finish by using the function return value. +' - As the user callback address is passed to the thread as argument, it cannot be modified while the thread is running. + + +'' thread Sub definition + Sub threadInkey (Byval p As Any Ptr) + If p > 0 Then '' test condition callback Function defined + Dim As Function (Byref As String) As Integer callback = p '' convert the any ptr to a callback Function pointer + Do + Dim As String s = Inkey + If s <> "" Then '' test condition key pressed + If callback(s) Then '' test condition to finish thread + Exit Do + End If + End If + Sleep 50 + Loop + End If + End Sub + +'' user callback Function definition + Function printInkey (Byref s As String) As Integer + If Asc(s) = 27 Then '' test condition key pressed = + Print + Return -1 '' order thread to finish + Else + Print s; + Return 0 '' order thread to continue + End If + End Function + +'' user main code + Dim As Any Ptr p = Threadcreate(@threadInkey, @printInkey) '' launch the thread, passing the callback Function address + Threadwait(p) '' wait for the thread finish +%% + {{fbdoc item="diff"}} - New to ""FreeBASIC"" diff --git a/doc/manual/cache/KeyPgReturn.wakka b/doc/manual/cache/KeyPgReturn.wakka index 1abc7c32d5..e923dd6735 100644 --- a/doc/manual/cache/KeyPgReturn.wakka +++ b/doc/manual/cache/KeyPgReturn.wakka @@ -11,8 +11,11 @@ Control flow statement to return from a procedure or ##[[KeyPgGosub|Gosub]]##. Because ##[[KeyPgReturn|Return]]## could mean return-from-gosub or return-from-procedure, ##[[KeyPgOptiongosub|Option Gosub]]## and ##[[KeyPgOptionnogosub|Option Nogosub]]## can be used to enable and disable ##[[KeyPgGosub|Gosub]]## support. When ##[[KeyPgGosub|Gosub]]## support is disabled, ##[[KeyPgReturn|Return]]## is then recognized as return-from-procedure. When ##[[KeyPgGosub|Gosub]]## support is enabled, ##[[KeyPgReturn|Return]]## is then recognized as return-from-gosub. - ##**Return**## (from procedure) is used inside a procedure to exit the procedure possibly with a return value. A ##[[KeyPgSub|Sub]]## cannot specify a return return value. In a ##[[KeyPgFunction|Function]]##, ##**Return**## must specify its return value. ##**Return** //expression//## is roughly equivalent to the ##Function = //expression// : [[KeyPgExit|Exit]] Function## idiom. - + ##**Return**## (from procedure) is used inside a procedure to exit the procedure possibly with a return value: + - A ##[[KeyPgSub|Sub]]## cannot specify a return return value. ##**Return**## is roughly equivalent to the ##[[KeyPgExit|Exit]] Sub## idiom. + - In a ##[[KeyPgFunction|Function]]##, ##**Return**## must specify its return value. ##**Return** //expression//## is roughly equivalent to the ##Function = //expression// : [[KeyPgExit|Exit]] Function## idiom. + + ##**Return**## (from gosub) is used to return control back to the statement immediately following a previous ##[[KeyPgGosub|Gosub]]## call. When used in combination with ##[[KeyPgGosub|Gosub]]##, no return value can be specified. If the optional ##//label//## is specified, execution continues at the specified label. If no ##[[KeyPgGosub|Gosub]]## was made, a runtime error is generated, and execution continues immediately after ##**Return**##. A ##[[KeyPgGosub|Gosub]]## should always have a matching ##**Return**## statement. However, if ##**Return**## (from gosub) is used where no ##[[KeyPgGosub|Gosub]]## was made, a run-time error is generated. diff --git a/doc/manual/cache/KeyPgScreengraphics.wakka b/doc/manual/cache/KeyPgScreengraphics.wakka index d37a130576..0d452caa75 100644 --- a/doc/manual/cache/KeyPgScreengraphics.wakka +++ b/doc/manual/cache/KeyPgScreengraphics.wakka @@ -59,6 +59,10 @@ __##flags## details:__ __Other details__ While in windowed mode, clicking on the window close button will add a keypress of ##([[KeyPgChr|Chr]](255) & "k")## to the ##[[KeyPgInkey|Inkey]]## buffer. Clicking on the Maximize window button will switch to fullscreen mode if possible. A successful ##**Screen**## call sets currently visible and working pages both to page number ##0##, resets the palette to the specified mode one (see [[GfxDefPalettes|Default palettes]]), resets the clipping region to the size of the screen, disables custom coordinates mappings, moves the graphics cursor to the center of the screen, moves the text cursor to the top-left corner of the screen (but never visible on any graphics screen), and sets foreground and background colors to bright white and black respectively. + +__Note on using ##Screen 0##__ + ##Screen 0## closes any graphics window, but also clears the console window if it exists. + ##Screen 0, , , SCREEN_EXIT## (with ##SCREEN_EXIT=&h80000000##) also closes any graphics window, but does not clear the console window if it exists (previous text is preserved). {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/gfx/screen.bas"}}%%(freebasic) diff --git a/doc/manual/cache/KeyPgSubPtr.wakka b/doc/manual/cache/KeyPgSubPtr.wakka index 71c2ed1789..e3fd928096 100644 --- a/doc/manual/cache/KeyPgSubPtr.wakka +++ b/doc/manual/cache/KeyPgSubPtr.wakka @@ -20,9 +20,11 @@ Data type that stores a pointer to a ##[[KeyPgSub|SUB]]## procedure The procedure must match the same ##[[KeyPgSub|Sub]]## declaration as the declared ##[[KeyPgSub|Sub]]## pointer. To call the subroutine assigned, use the ##//variable//## name as if it were a normal declared ##[[KeyPgSub|Sub]]##. + + One of the primary uses for procedure pointers is to create callback procedures. A callback procedure is a procedure created in the user program that is called by another procedure either from the user own code space or from an external library. {{fbdoc item="ex"}} -{{fbdoc item="filename" value="examples/manual/datatype/funcptr.bas"}}%%(freebasic) +{{fbdoc item="filename" value="examples/manual/datatype/subptr.bas"}}%%(freebasic) sub Hello() print "Hello" end sub @@ -39,6 +41,76 @@ Data type that stores a pointer to a ##[[KeyPgSub|SUB]]## procedure x() %% +{{fbdoc item="filename" value="examples/manual/datatype/subptr2.bas"}}%%(freebasic) +Sub s0 () + Print "'s0 ()'" +End Sub + +Sub s1 (Byval I As Integer) + Print "'s1 (Byval As Integer)'", I +End Sub + +Sub s2 (Byref S As String, Byval D As Double) + Print "'s2 (Byref As String, Byval As Double)'", S, D +End Sub + +Dim s0_ptr As Sub () = @s0 +Dim s1_ptr As Sub (Byval I As Integer) = @s1 +Dim s2_ptr As Sub (Byref S As String, Byval D As Double) = @s2 + +s0_ptr() +s1_ptr(3) +s2_ptr("PI", 3.14) +%% +{{fbdoc item="filename" value="examples/manual/datatype/subptr3.bas"}}%%(freebasic) +' Example of advanced callback Sub mechanism to implement a key pressed event: +' (the user callback Sub address can be modified while the event thread is running) +' - An asynchronous thread tests the keyboard in a loop, and calls a user callback Sub each time a key is pressed. +' - An UDT groups the common variables used (callback Sub pointer, character of key pressed, thread end flag), +' and the static thread Sub plus the thread handle. +' - An UDT instance pointer is passed to the thread, which then transmits it to the callback Sub each time. +' - The callback Sub prints the character of the key pressed character, +' but if the key pressed is it orders the thread to finish. +' - As the user callback pointer is a member field of the UDT, it can be modified while the thread is running. + + +'' UDT for thread environment + Type threadUDT + Dim As Sub (Byval As ThreadUDT Ptr) callback '' callback Sub pointer + Dim As Integer threadEnd '' thread end flag + Dim As String s '' character of the key pressed + Declare Static Sub threadInkey (Byval p As Any Ptr) '' static thread Sub + Dim As Any Ptr threadHandle '' handle to the thread + End Type + +'' thread Sub definition + Sub threadUDT.threadInkey (Byval p As Any Ptr) + Dim As threadUDT Ptr pt = p '' convert the any ptr to a threadUDT pointer + Do + pt->s = Inkey + If pt->s <> "" Andalso pt->callback > 0 Then '' test condition key pressed & callback Sub defined + pt->callback(p) + End If + Sleep 50 + Loop Until pt->threadEnd '' test condition to finish thread + End Sub + +'' user callback Sub definition + Sub printInkey (Byval pt As threadUDT Ptr) + If Asc(pt->s) = 27 Then '' test condition key pressed = + pt->threadEnd = -1 '' order thread to finish + Print + Else + Print pt->s; + End If + End Sub + +'' user main code + Dim As ThreadUDT t '' create an instance of threadUDT + t.threadHandle = Threadcreate(@threadUDT.threadInkey, @t) '' launch the thread, passing the instance address + t.callback = @printInkey '' initialize the callback Sub pointer + Threadwait(t.threadHandle) '' wait for the thread finish +%% {{fbdoc item="diff"}} - New to ""FreeBASIC"" diff --git a/doc/manual/cache/ProPgArrays.wakka b/doc/manual/cache/ProPgArrays.wakka index d7a23d7c84..c89695d7cc 100644 --- a/doc/manual/cache/ProPgArrays.wakka +++ b/doc/manual/cache/ProPgArrays.wakka @@ -23,7 +23,7 @@ next {{fbdoc item="section" value="Sizes and bounds"}} The size of an array is equal to the number of elements it stores at any given time. An array can have a size of zero (0), meaning it's not storing any values at the moment--it's //empty//. If an array's size is greater than zero, that many elements are being stored. An array's size is equal to one more than the difference between its upper and lower bounds, or ##[[KeyPgUbound|ubound]](//array//) - [[KeyPgLbound|lbound]](//array//) + 1##. - The lower and upper bounds not only determine the size of an array, but also the valid positions of individual elements. For example, an array with lower and upper bounds of zero (0) and four (4) stores five (5) elements, the first element being at position 0, the last at position 5. These bounds may be specified when the array is declared, or, for some arrays, changed by resizing the array. An array's lower and upper bounds can be retrieved using ##[[KeyPgLbound|Lbound]]## and ##[[KeyPgUbound|Ubound]]##, respectively. + The lower and upper bounds not only determine the size of an array, but also the valid positions of individual elements. For example, an array with a lower bound of zero (0) and an upper bound of four (4), stores five (5) elements, the first element being at position 0, the last at position 4. These bounds may be specified when the array is declared, or, for some arrays, changed by resizing the array. An array's lower and upper bounds can be retrieved using ##[[KeyPgLbound|Lbound]]## and ##[[KeyPgUbound|Ubound]]##, respectively. When creating or resizing an array, if a lower bound is not specified it defaults to zero (0). diff --git a/doc/manual/cache/TutPointers.wakka b/doc/manual/cache/TutPointers.wakka index f30b2e9009..5c32d1820d 100644 --- a/doc/manual/cache/TutPointers.wakka +++ b/doc/manual/cache/TutPointers.wakka @@ -9,7 +9,7 @@ To understand pointers, think of an egg carton that has numbers 1 through 12 pri Normally, you would access the data directly through the use of variables. When you DIMension a variable of a particular type, you are setting aside storage space for the data. You do not need to know, or care, where the data resides since you can access the data directly through the variable. This is like reaching out and picking up the egg in hole 1 (reading the data) or putting an egg in hole 1 (setting the data) without looking at the numbers written on the bottom of the hole. -Using pointers is a bit different. Imagine you have a little scrap of paper that will represent our pointer. Right now it is blank and doesn't point to anything. This undefined pointer can't be used until it is initialized. To initialize the pointer, write a 1 on it. Now our pointer is "pointing" to hole 1 in our egg carton. To put data (an egg) in hole 1, we look at our scrap of paper, match it to hole 1 and place the egg in the hole. To retrieve the egg we do just the opposite. We match our slip of paper to hole 1 and then grab the egg. All the putting and getting of the egg has to be done through the slip of paper and is called dereferencing the pointer. That is, we get to the data through the reference contained in the pointer, the number 1. The pointer doesn't contain the data; it contains a reference to the data. +Using pointers is a bit different. Imagine you have a little scrap of paper that will represent our pointer. Right now it is blank and doesn't point to anything. This undefined pointer can't be used until it is initialized. To initialize the pointer, write a 1 on it. Now our pointer is "pointing" to hole 1 in our egg carton. To put data (an egg) in hole 1, we look at our scrap of paper, match it to hole 1 and place the egg in the hole. To retrieve the egg we do just the opposite. We match our slip of paper to hole 1 and then grab the egg. All the putting and getting of the egg has to be done through the slip of paper and is called dereferencing the pointer. That is, we get to the data through the referring address contained in the pointer, the number 1. The pointer doesn't contain the data; it contains a referring address to the data. In ""FreeBASIC"" we define a pointer using the [[KeyPgDim|Dim]] and [[KeyPgPtr|Ptr]] statements: @@ -36,7 +36,7 @@ Once we have initialized the pointer, we can now use it: print "aptr: "; *aptr %%## -Notice the ***** prefix on aptr. The * is the reference operator. This is like matching the number on the slip of paper to the number on the hole in the egg carton. By using the * operator, we are able to get at the data (egg) contained in the hole pointed at by aptr. +Notice the ***** prefix on aptr. The * is the dereference operator. This is like matching the number on the slip of paper to the number on the hole in the egg carton. By using the * operator, we are able to get at the data (egg) contained in the hole pointed at by aptr. Here is a complete example program: @@ -112,7 +112,7 @@ The function pSetString uses a temporary [[KeyPgZstring|zstring]] sz, to [[KeyPg sz = allocate(len(s) + 1) %%## -Once we have allocated space for the string, we use the reference operator * to load the data into the memory location. +Once we have allocated space for the string, we use the dereference operator * to load the data into the memory location. ##%%(freebasic) 'load the string into the memory location @@ -126,12 +126,12 @@ We then return a pointer (the address of the string) back to our type, which is return sz %%## -We can now reference the string in our type using the reference operator. +We can now dereference the string in our type using the dereference operator. ##%%(freebasic) print "aptr: "; *mytype.sptr %%## -Pointers can be confusing for the uninitiated, however they need not be if it is kept in mind that the pointer doesn't contain data, it simply points to some data. The pointer is a memory address, and you manipulate that data through the reference operator *. It really isn't much different than a normal variable. +Pointers can be confusing for the uninitiated, however they need not be if it is kept in mind that the pointer doesn't contain data, it simply points to some data. The pointer is a memory address, and you manipulate that data through the dereference operator *. It really isn't much different than a normal variable. //Last reviewed by ""sancho3"" on February 07, 2018// \ No newline at end of file diff --git a/doc/manual/cache/TutPointersData.wakka b/doc/manual/cache/TutPointersData.wakka index eb081b7991..90bd1c69b8 100644 --- a/doc/manual/cache/TutPointersData.wakka +++ b/doc/manual/cache/TutPointersData.wakka @@ -1,7 +1,7 @@ {{fbdoc item="title" value="Pointers, Data Types and Memory"}}---- //Written by [[WikiRick|rdc]]// -If you read the article [[TutPointers|Introduction to Pointers]] you know that pointers contain memory location addresses. You can manipulate the data in these memory locations using the reference operator *. Using pointers with single data item isn't a problem, but what if you need to store multiple data items together and manipulate them using a pointer? It can get a bit tricky unless you understand how data is stored in memory. +If you read the article [[TutPointers|Introduction to Pointers]] you know that pointers contain memory location addresses. You can manipulate the data in these memory locations using the dereference operator *. Using pointers with single data item isn't a problem, but what if you need to store multiple data items together and manipulate them using a pointer? It can get a bit tricky unless you understand how data is stored in memory. A single memory location in a computer is 1 byte long. Big enough to hold a single ANSI character (as opposed to Unicode characters, which are wide characters and are two bytes. We won't be discussing Unicode characters in this article.) However, all data types are not a single byte in width. Here is a simple program that displays the length in bytes of each data type. @@ -93,7 +93,7 @@ Sleep In this program we dimension two variables, an [[KeyPgInteger|integer]] and an [[KeyPgInteger|integer]] [[KeyPgPointer|pointer]], aptr. Aptr will point to our memory buffer that will contain two integers. The [[KeyPgAllocate|allocate]] function requires the size of the buffer we need, so we multiply the size of an [[KeyPgInteger|integer]] by 2 to reserve 8/16 bytes of memory (on 32/64bit systems, each integer will take 4/8 bytes of space (on 32/64bit systems). -After the allocation process, aptr contains the address of the first byte of our memory buffer. Storing the first integer is simply a matter of using the reference operator and setting the value to 1. To print out the value, we again just use *aptr. +After the allocation process, aptr contains the address of the first byte of our memory buffer. Storing the first integer is simply a matter of using the dereference operator and setting the value to 1. To print out the value, we again just use *aptr. Now, let me ask you a question: How does the compiler know that the value 1 requires 4/8 bytes (on 32/64bit systems) and not 1 or 2 bytes? Because we dimensioned aptr as an //integer ptr//. The compiler knows that an integer takes 4/8 bytes (on 32/64bit systems) and so loads the data into four bytes of memory. This is why when we print out the value we get 1 and not some strange number. @@ -104,7 +104,7 @@ To load the second value into our buffer, we use: %%## This may look a little strange at first glance. Aptr points to the first byte in our memory buffer. An integer is 4/8 bytes long (on 32/64bit systems), so to get to the next integer byte position, we must add 4/8 to the address (value of aptr). But the compiler knows that the data being used with this pointer is of size Integer or 4/8 bytes (on 32/64bit systems), so to access the second element, you need to only add 1 to the pointer, which can be expressed as *(aptr + 1). -We need the parenthesis around the add operation because the reference operator * has a higher precedence than +. The parenthesis ensure that we perform the add operation first, and then apply the indirection operator. +We need the parenthesis around the add operation because the dereference operator * has a higher precedence than +. The parenthesis ensure that we perform the add operation first, and then apply the indirection operator. Notice that we didn't increment aptr directly. If we did, aptr would no longer point to the start of the memory buffer and the program would crash when we deallocated the buffer since it would [[KeyPgDeallocate|deallocate]] memory outside the memory buffer. If the need arises to directly increment a pointer, then create a temporary pointer variable and increment that, rather than the pointer used in the original allocation. From a8d5d028a162f77db45696f5219cd1e8e1897294 Mon Sep 17 00:00:00 2001 From: coderJeff Date: Mon, 3 Sep 2018 00:33:56 -0400 Subject: [PATCH 3/7] fbdoc: wiki snapshot 2018-09-02 --- doc/manual/cache/CatPgFullIndex.wakka | 4 +- doc/manual/cache/CatPgOpIndex.wakka | 6 +- doc/manual/cache/CatPgOpMemory.wakka | 9 +- doc/manual/cache/CatPgVariables.wakka | 14 ++-- doc/manual/cache/CompilerCmdLine.wakka | 2 +- doc/manual/cache/CompilerOptw.wakka | 6 +- doc/manual/cache/GlossaryIndex.wakka | 2 +- doc/manual/cache/KeyPgAllocate.wakka | 2 +- doc/manual/cache/KeyPgAny.wakka | 2 +- doc/manual/cache/KeyPgConstructor.wakka | 4 +- doc/manual/cache/KeyPgDestructor.wakka | 4 +- doc/manual/cache/KeyPgDrawString.wakka | 2 + doc/manual/cache/KeyPgOpCast.wakka | 4 +- doc/manual/cache/KeyPgOpDelete.wakka | 29 +++---- doc/manual/cache/KeyPgOpLet.wakka | 6 +- doc/manual/cache/KeyPgOpNew.wakka | 25 +++--- doc/manual/cache/KeyPgOpPlacementNew.wakka | 10 ++- doc/manual/cache/KeyPgOperator.wakka | 95 ++++------------------ doc/manual/cache/KeyPgPragma.wakka | 2 +- doc/manual/cache/PrintToc.wakka | 10 ++- doc/manual/cache/ProPgCtorsDtors.wakka | 6 +- 21 files changed, 96 insertions(+), 148 deletions(-) diff --git a/doc/manual/cache/CatPgFullIndex.wakka b/doc/manual/cache/CatPgFullIndex.wakka index ae631845cc..21e48bdcfb 100644 --- a/doc/manual/cache/CatPgFullIndex.wakka +++ b/doc/manual/cache/CatPgFullIndex.wakka @@ -213,7 +213,7 @@ Alphabetical listing of keywords, macros and procedures. - {{fbdoc item="keyword" value="KeyPgDefuint|DEFUINT"}} - {{fbdoc item="keyword" value="KeyPgDefulongint|DEFULONGINT"}} - {{fbdoc item="keyword" value="KeyPgDefushort|DEFUSHORT"}} - - {{fbdoc item="keyword" value="KeyPgOpDelete|DELETE"}} + - {{fbdoc item="keyword" value="KeyPgOpDelete|DELETE (Statement)"}} - {{fbdoc item="keyword" value="KeyPgDestructor|DESTRUCTOR"}} - {{fbdoc item="keyword" value="KeyPgModuleDestructor|DESTRUCTOR (Module)"}} - {{fbdoc item="keyword" value="KeyPgDim|DIM"}} @@ -367,7 +367,7 @@ Alphabetical listing of keywords, macros and procedures. - {{fbdoc item="keyword" value="KeyPgNaked|NAKED"}} - {{fbdoc item="keyword" value="KeyPgName|NAME"}} - {{fbdoc item="keyword" value="KeyPgNamespace|NAMESPACE"}} - - {{fbdoc item="keyword" value="KeyPgOpNew|NEW"}} + - {{fbdoc item="keyword" value="KeyPgOpNew|NEW (Expression)"}} - {{fbdoc item="keyword" value="KeyPgOpPlacementNew|NEW (Placement)"}} - {{fbdoc item="keyword" value="KeyPgNext|NEXT"}} - {{fbdoc item="keyword" value="KeyPgResumenext|NEXT (RESUME)"}} diff --git a/doc/manual/cache/CatPgOpIndex.wakka b/doc/manual/cache/CatPgOpIndex.wakka index 9131e56dba..3c91d06431 100644 --- a/doc/manual/cache/CatPgOpIndex.wakka +++ b/doc/manual/cache/CatPgOpIndex.wakka @@ -84,9 +84,11 @@ List of operators used in FreeBASIC. - {{fbdoc item="keyword" value="KeyPgOpIs|IS (Run-time type information operator)"}} {{fbdoc item="section" value="Memory Operators"}} - - {{fbdoc item="keyword" value="KeyPgOpNew|New"}} + - {{fbdoc item="keyword" value="KeyPgOpNew|New Expression"}} + - {{fbdoc item="keyword" value="KeyPgOpNewOverload|New Overload"}} - {{fbdoc item="keyword" value="KeyPgOpPlacementNew|Placement New"}} - - {{fbdoc item="keyword" value="KeyPgOpDelete|Delete"}} + - {{fbdoc item="keyword" value="KeyPgOpDelete|Delete Statement"}} + - {{fbdoc item="keyword" value="KeyPgOpDeleteOverload|Delete Overload"}} {{fbdoc item="section" value="Iteration Operators"}} - {{fbdoc item="keyword" value="KeyPgOpFor|For"}}, [[KeyPgOpNext|Next]], and [[KeyPgOpStep|Step]] diff --git a/doc/manual/cache/CatPgOpMemory.wakka b/doc/manual/cache/CatPgOpMemory.wakka index 2a614b4322..f632db8663 100644 --- a/doc/manual/cache/CatPgOpMemory.wakka +++ b/doc/manual/cache/CatPgOpMemory.wakka @@ -3,12 +3,15 @@ Operators that work with memory The memory operators provide a way to dynamically allocate and deallocate variables and objects. -<<=={{fbdoc item="keyword" value="KeyPgOpNew|Operator New"}}== +<<=={{fbdoc item="keyword" value="KeyPgOpNew|Operator New Expression"}}== Allocates memory for and constructs objects. + =={{fbdoc item="keyword" value="KeyPgOpNewOverload|Operator New Overload"}}== + Overloads memory allocation process of Operator New Expression when applying to UDT. =={{fbdoc item="keyword" value="KeyPgOpPlacementNew|Operator Placement New"}}== Constructs objects at a specified memory location. -<<>>=={{fbdoc item="keyword" value="KeyPgOpDelete|Operator Delete"}}== +<<>>=={{fbdoc item="keyword" value="KeyPgOpDelete|Operator Delete Statement"}}== Destroys and deallocates memory for objects. ->>::c:: + =={{fbdoc item="keyword" value="KeyPgOpDeleteOverload|Operator Delete Overload"}}== + Overloads memory deallocation process of Operator Delete Statement when applying to UDT.>>::c:: {{fbdoc item="back" value="CatPgOperators|Operators"}} \ No newline at end of file diff --git a/doc/manual/cache/CatPgVariables.wakka b/doc/manual/cache/CatPgVariables.wakka index a8335ab481..14953af6ce 100644 --- a/doc/manual/cache/CatPgVariables.wakka +++ b/doc/manual/cache/CatPgVariables.wakka @@ -1,19 +1,19 @@ {{fbdoc item="title" value="Variable Declarations"}}---- Statements to declare and allocate space for variables. -<<=={{fbdoc item="keyword" value="KeyPgDim|DIM"}}== +<<**{{fbdoc item="keyword" value="KeyPgDim|DIM"}}** Declares a variable at the current scope. -=={{fbdoc item="keyword" value="KeyPgConst|CONST"}}== +**{{fbdoc item="keyword" value="KeyPgConst|CONST"}}** Declares a non-modifiable variable. -=={{fbdoc item="keyword" value="KeyPgScope|SCOPE"}}== +**{{fbdoc item="keyword" value="KeyPgScope|SCOPE"}}** Begins a new scope block. -=={{fbdoc item="keyword" value="KeyPgStatic|STATIC"}}== +**{{fbdoc item="keyword" value="KeyPgStatic|STATIC"}}** Declares variables in a procedure that retain their value between calls. -<<>>=={{fbdoc item="keyword" value="KeyPgShared|SHARED"}}== +<<>>**{{fbdoc item="keyword" value="KeyPgShared|SHARED"}}** Used with ##[[KeyPgDim|Dim]]## allows variables to be visible throughout a module. -=={{fbdoc item="keyword" value="KeyPgVar|VAR"}}== +**{{fbdoc item="keyword" value="KeyPgVar|VAR"}}** Declares variables where the data type is implied from an initializer. -=={{fbdoc item="keyword" value="KeyPgByrefVariables|BYREF (variables)"}}== +**{{fbdoc item="keyword" value="KeyPgByrefVariables|BYREF (variables)"}}** Used with ##[[KeyPgDim|Dim]]## or ##[[KeyPgStatic|Static]]## or ##[[KeyPgVar|Var]]## allows to declare references. >> diff --git a/doc/manual/cache/CompilerCmdLine.wakka b/doc/manual/cache/CompilerCmdLine.wakka index 187dd45c35..334850b1fa 100644 --- a/doc/manual/cache/CompilerCmdLine.wakka +++ b/doc/manual/cache/CompilerCmdLine.wakka @@ -132,7 +132,7 @@ Using the **fbc** command-line. =={{fbdoc item="keyword" value="CompilerOptcupp|-C"}}== Do not delete the object file(s) =={{fbdoc item="keyword" value="CompilerOptw|-w < value >"}}== - Set min warning level: ##all##, ##pedantic##, ##next## or a value + Set min warning level: ##all##, ##param##, ##escape##, ##pedantic##, ##next##, ##constness## or a value =={{fbdoc item="keyword" value="CompilerOptmaxerr|-maxerr < val >"}}== Only stop parsing if errors occurred =={{fbdoc item="keyword" value="CompilerOptnoerrline|-noerrline"}}== diff --git a/doc/manual/cache/CompilerOptw.wakka b/doc/manual/cache/CompilerOptw.wakka index 1687a73d39..944501b2fb 100644 --- a/doc/manual/cache/CompilerOptw.wakka +++ b/doc/manual/cache/CompilerOptw.wakka @@ -2,7 +2,7 @@ Set minimum warning level. {{fbdoc item="syntax"}}## - **-w** //level// | **all** | **param** | **escape** | **pedantic** | **next** + **-w** //level// | **all** | **param** | **escape** | **pedantic** | **next** | **constness** ## {{fbdoc item="param"}} ##//level//## @@ -17,11 +17,13 @@ Set minimum warning level. Equivalent to specifying the ##**param**## and ##**escape**## arguments, plus length checking of parameters passed ##[[KeyPgByval|ByVal]]## and of any ##[[KeyPgCptr|Cptr]]## converting to pointer only. ##**next**## Warn when ##[[KeyPgNext|Next]]## is followed by an identifier. + ##**constness**## + Warn when ##[[KeyPgConstQualifier|CONST (Qualifier)]]## is discarded in an assignment. {{fbdoc item="desc"}} The ##-w## compiler option determines which compiler warnings, if any, are output. Each possible warning is associated with a warning level, starting from zero (##0##) and increasing with the potential problems that may occur. A significantly high ##//level//## value will have the effect of suppressing all warning messages. - Note that the ##**param**##, ##**escape**##, ##**pedantic**## and ##**next**## arguments provide additional warnings not ordinarily output, even by default. + Note that the ##**param**##, ##**escape**##, ##**pedantic**##, ##**next**## and ##**constness**## arguments provide additional warnings not ordinarily output, even by default. If the ##**-w**## option is not specified, it's as if ##**-w 0**## was used. The ##**-w**## option can be specified multiple times. diff --git a/doc/manual/cache/GlossaryIndex.wakka b/doc/manual/cache/GlossaryIndex.wakka index 90e16bd060..b5a3b69382 100644 --- a/doc/manual/cache/GlossaryIndex.wakka +++ b/doc/manual/cache/GlossaryIndex.wakka @@ -130,7 +130,7 @@ Brief definitions and explanations for words and phrases used in the ""FreeBASIC Refers to the internal data structure used by the compiler and runtime library for managing variable length strings and arrays. **destroy (TYPE or CLASS)** - The act of deconstructing and deallocating memory for an object instance. When an object is destroyed, its destructor is called. This happens automatically when an object goes out of scope, or when ##[[KeyPgOpDelete|Delete]]## is called with a pointer to an object. + The act of deconstructing and deallocating memory for an object instance. When an object is destroyed, its destructor is called. This happens automatically when an object goes out of scope, or when ##[[KeyPgOpDelete|Delete (Statement)]]## is called with a pointer to an object. **destructor (module)** A special type of module-level procedure that is automatically called at program termination. See ##[[KeyPgModuleDestructor|Destructor (Module)]]##. diff --git a/doc/manual/cache/KeyPgAllocate.wakka b/doc/manual/cache/KeyPgAllocate.wakka index 7a2458678f..b76b07e904 100644 --- a/doc/manual/cache/KeyPgAllocate.wakka +++ b/doc/manual/cache/KeyPgAllocate.wakka @@ -17,7 +17,7 @@ Allocates a block of memory from the free store {{fbdoc item="desc"}} Attempts to allocate, or reserve, ##//count//## number of bytes from the free store (heap). The newly allocated memory is not initialized. - As the initial value of newly allocated memory is unspecified, **Allocate** must not be directly used with ##[[KeyPgString|String]]## or ##[[KeyPgType|UDT]]## containing string, because the string descriptor being not cleared (containing random data), that may induce corrupted string or more (trying to write to a random place in memory or trying to deallocate a random pointer). It is mandatory in that case (with string or UDT containing string) to use ##[[KeyPgCallocate|Callocate]]## (clearing memory), or ##[[KeyPgOpNew|New]]## (calling constructor) in case of **UDT**, or at worst after **Allocate** to explicitly clear the descriptor (setting to 0) before the first string use. + As the initial value of newly allocated memory is unspecified, **Allocate** must not be directly used with ##[[KeyPgString|String]]## or ##[[KeyPgType|UDT]]## containing string, because the string descriptor being not cleared (containing random data), that may induce corrupted string or more (trying to write to a random place in memory or trying to deallocate a random pointer). It is mandatory in that case (with string or UDT containing string) to use ##[[KeyPgCallocate|Callocate]]## (clearing memory), or ##[[KeyPgOpNew|New Expression]]## (calling constructor) in case of **UDT**, or at worst after **Allocate** to explicitly clear the descriptor (setting to 0) before the first string use. The pointer that is returned is an [[KeyPgAny|any]] [[KeyPgPtr|ptr]] and points to the start of the allocated memory. This pointer is guaranteed to be unique, even if ##//count//## is zero. diff --git a/doc/manual/cache/KeyPgAny.wakka b/doc/manual/cache/KeyPgAny.wakka index 3aff8607bc..0a464c32a6 100644 --- a/doc/manual/cache/KeyPgAny.wakka +++ b/doc/manual/cache/KeyPgAny.wakka @@ -41,7 +41,7 @@ The ##**Any**## keyword is used as a placeholder for a type or value in various Comparison to ""C/C++"": This matches the behavior of a variable declaration without initialization value in ""C/C++"". - Similar to **##Any##** initializers for variables, **##Any##** can also be used with the ##[[KeyPgOpNew|New]]## or ##[[KeyPgOpPlacementNew|Placement New]]## operators in order to leave the newly created object uninitialized (only allowed with data types that do not have constructors). + Similar to **##Any##** initializers for variables, **##Any##** can also be used with the ##[[KeyPgOpNew|New Expression]]## or ##[[KeyPgOpPlacementNew|Placement New]]## operators in order to leave the newly created object uninitialized (only allowed with data types that do not have constructors). - ""Instr/InstrRev"": **##Any##** can be used with ##[[KeyPgInstr|Instr]]## or ##[[KeyPgInstrrev|InstrRev]]## as a qualifier for the ##//substring//## parameter, to indicate that any individual character in it may be matched. diff --git a/doc/manual/cache/KeyPgConstructor.wakka b/doc/manual/cache/KeyPgConstructor.wakka index 5aed7db721..f30292da9c 100644 --- a/doc/manual/cache/KeyPgConstructor.wakka +++ b/doc/manual/cache/KeyPgConstructor.wakka @@ -24,7 +24,7 @@ Called automatically when a class or user defined type is created A constructor method is passed a hidden ##[[KeyPgThis|this]]## parameter having the same type as ##//typename//##. ##[[KeyPgThis|this]]## is optionally used to access the fields of the ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]## which is to be initialized in the ##**Constructor**## method. - Constructors are called when declaring global or local static instances of ##//typename//## and when allocating ##//typename//## dynamically using the ##[[KeyPgOpNew|New]]## operator. See examples below for different constructor syntaxes. + Constructors are called when declaring global or local static instances of ##//typename//## and when allocating ##//typename//## dynamically using the ##[[KeyPgOpNew|New Expression]]## operator. See examples below for different constructor syntaxes. A copy ##**Constructor**## is a special constructor that initializes a new object from an existing object. There are three general cases where the copy ##**Constructor**## is called: when instantiating one object and initializing it with another object (in one instruction), when passing an object by value, when an object is returned from a function by value (by using ##[[KeyPgReturn|Return]] //x//## statement). Note: When an object is returned from a function by value, but by using ##**Function** = //x//## (or ##//function_identifier// = //x//##) assignment, the ##**Constructor**## is called once at first, and then the ##[[KeyPgOpLet|Let (Assign)]]## operator at each assignment. @@ -189,7 +189,7 @@ Sleep {{fbdoc item="see"}} - ##[[KeyPgClass|Class]]## - ##[[KeyPgModuleConstructor|Constructor (Module)]]## - - ##[[KeyPgOpNew|New]]## + - ##[[KeyPgOpNew|New Expression]]## - ##[[KeyPgDestructor|Destructor]]## - ##[[KeyPgType|Type]]## - [[ProPgDataConversion|Coercion and Conversion]] diff --git a/doc/manual/cache/KeyPgDestructor.wakka b/doc/manual/cache/KeyPgDestructor.wakka index 1f6c0170a5..55e098d746 100644 --- a/doc/manual/cache/KeyPgDestructor.wakka +++ b/doc/manual/cache/KeyPgDestructor.wakka @@ -16,7 +16,7 @@ Called automatically when a class or user defined type goes out of scope or is d name of the ##[[KeyPgType|Type]]## of ##[[KeyPgClass|Class]]## {{fbdoc item="desc"}} - The destructor method is called when a user defined ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]## variable goes out of scope or is destroyed explicitly with the ##[[KeyPgOpDelete|Delete]]## operator. + The destructor method is called when a user defined ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]## variable goes out of scope or is destroyed explicitly with the ##[[KeyPgOpDelete|Delete Statement]]## operator. ##//typename//## is the name of the type for which the ##**Destructor**## method is declared and defined. Name resolution for ##//typename//## follows the same rules as procedures when used in a ##[[KeyPgNamespace|Namespace]]##. @@ -77,7 +77,7 @@ Destroying: main.x {{fbdoc item="see"}} - ##[[KeyPgClass|Class]]## - ##[[KeyPgConstructor|Constructor]]## - - ##[[KeyPgOpDelete|Delete]]## + - ##[[KeyPgOpDelete|Delete Statement]]## - ##[[KeyPgModuleDestructor|Destructor (Module)]]## - ##[[KeyPgType|Type]]## diff --git a/doc/manual/cache/KeyPgDrawString.wakka b/doc/manual/cache/KeyPgDrawString.wakka index e9f9b9a02b..08ba74e232 100644 --- a/doc/manual/cache/KeyPgDrawString.wakka +++ b/doc/manual/cache/KeyPgDrawString.wakka @@ -43,6 +43,8 @@ Graphics statement to render text to an image or screen. Note: If a custom font isn't supplied, **##Draw String##** will default to the standard font, as used by ##[[KeyPgPrint|Print]]##, with character size dictated by ##[[KeyPgWidth|Width]]##. ##//method//## - if passed - will be ignored, and the text will be drawn using the color supplied, with a transparent background. + **##Draw String##** coordinates are affected by custom coordinates system set via ##[[KeyPgWindow|Window]]## and ##[[KeyPgViewgraphics|View (Graphics)]]## statements, and the drawn text respects clipping rectangle set by ##[[KeyPgViewgraphics|View (Graphics)]]##. + ==The custom font format:== The font is stored in a standard ##[[KeyPgGetgraphics|Get]]##/##[[KeyPgPutgraphics|Put]]## buffer; the font has to be stored in a buffer using the same depth as the current color depth, otherwise **##Draw String##** will bump out with an illegal function call runtime error. diff --git a/doc/manual/cache/KeyPgOpCast.wakka b/doc/manual/cache/KeyPgOpCast.wakka index f1e834b47f..7dc1eefc6f 100644 --- a/doc/manual/cache/KeyPgOpCast.wakka +++ b/doc/manual/cache/KeyPgOpCast.wakka @@ -2,7 +2,7 @@ Operator to convert a UDT (User Defined Type) variable into a specified data type {{fbdoc item="syntax"}}## - { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] | [[KeyPgEnum|Enum]] } //typename// + { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] } //typename// [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **cast** () [ [[KeyPgByrefFunction|byref]] ] [[KeyPgAs|as]] [[DataType|datatype]] ... End { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] } @@ -258,7 +258,7 @@ Sleep - Only available in the //[[CompilerOptlang|-lang fb]]// dialect. {{fbdoc item="diff"}} - - New to ""FreeBASIC"" + - New to ""FreeBASIC"". {{fbdoc item="see"}} - ##[[KeyPgCast|Cast]]## diff --git a/doc/manual/cache/KeyPgOpDelete.wakka b/doc/manual/cache/KeyPgOpDelete.wakka index c7da9a6531..9e1bdd6a52 100644 --- a/doc/manual/cache/KeyPgOpDelete.wakka +++ b/doc/manual/cache/KeyPgOpDelete.wakka @@ -1,10 +1,6 @@ -{{fbdoc item="title" value="Operator Delete"}}---- -Operator to delete data allocated with the ##[[KeyPgOpNew|New]]## operator +{{fbdoc item="title" value="Operator Delete Statement"}}---- +Operator to destroy data and free memory allocated with the ##[[KeyPgOpNew|Operator New Expression]]## -{{fbdoc item="syntax"}}## - [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **delete** ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) - [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **delete[]** ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) -## {{fbdoc item="usage"}}## **Delete** //buf// //or// @@ -12,23 +8,23 @@ Operator to delete data allocated with the ##[[KeyPgOpNew|New]]## operator ## {{fbdoc item="param"}} ##//buf//## - A pointer to memory that has been allocated by ##[[KeyPgOpNew|New]]## or ##[[KeyPgOpNew|New]][]## (a typed pointer must be provided in accordance to the data type to delete). + A pointer to memory that has been allocated by ##[[KeyPgOpNew|New Expression]]## operator or ##**New[] Expression**## operator, the array-version of ##[[KeyPgOpNew|New Expression]]## operator (a typed pointer must be provided in accordance to the data type to delete). {{fbdoc item="desc"}} - ##**Delete**## is used to destroy and free the memory of an object created with ##[[KeyPgOpNew|New]]##. When deleting a TYPE, its destructor will be called. ##**Delete**## should only be used with addresses returned from ##[[KeyPgOpNew|New]]##. + The ##**Delete Statement**## operator is used to destroy and free the memory of an object created with ##[[KeyPgOpNew|New Expression]]## operator. When deleting a TYPE, its destructor will be called. ##**Delete Statement**## operator should only be used with addresses returned from ##[[KeyPgOpNew|New Expression]]## operator. - The array version of ##**Delete**##, ##**Delete[]**##, is used to destroy an array of objects previously created with ##[[KeyPgOpNew|New]][]##. Destructors will be called here as well. + The array version of ##**Delete Statement**## operator, ##**Delete[] Statement**## operator, is used to destroy an array of objects previously created with ##**New[] Expression**## operator, the array-version of ##[[KeyPgOpNew|New Expression]]## operator. Destructors will be called here as well. - ##**Delete**## must be used with addresses returned from ##[[KeyPgOpNew|New]]##, and ##**Delete[]**## with ##[[KeyPgOpNew|New]][]##. You cannot mix and match the different versions of the operators. + ##**Delete Statement**## operator must be used with addresses returned from ##[[KeyPgOpNew|New Expression]]## operator, and ##**Delete[] Statement**## operator with ##**New[] Expression**## operator, the array-version of ##[[KeyPgOpNew|New Expression]]## operator. You cannot mix and match the different versions of the operators. - After the memory is deleted, the ##//buf//## pointer will be pointing at invalid memory. Calling ##**Delete**## twice on the same pointer value leads to undefined behaviour. It may be a good idea to set the //##buf//## pointer to null (##0##), in order to guard against later code using it accidentally, since null pointer dereferences are easier to find and debug. + After the memory is deleted, the ##//buf//## pointer will be pointing at invalid memory. Calling ##**Delete Expression**## twice on the same pointer value leads to undefined behavior. It may be a good idea to set the //##buf//## pointer to null (##0##), in order to guard against later code using it accidentally, since null pointer dereferences are easier to find and debug. - Calling ##**Delete**## on a null pointer induces no action. + Calling ##**Delete Statement**## operator on a null pointer induces no action. - This operator can be overloaded for user-defined types as a member ##[[KeyPgOperator|Operator]]##. + The memory deallocation process part provided by the ##**Delete Statement**## operator can be overloaded for user-defined types as a member operator ##[[KeyPgOpDeleteOverload|Delete Overload]]##. The previous process part for data destruction can never be modified. - **Note:** Any operator ##**Delete[]**## (or the only overload operator ##**Delete**##) is not compatible with polymorphism, even using ##[[KeyPgOverride|Override]]## ##[[KeyPgVirtual|Virtual]]## ##[[KeyPgDestructor|Destructor]]## that may in addition induce crashing. - Instead of having to call such an operator ##**Delete([])**## on derived-type pointer, the safest way is to simply call (on base-type pointer) an overridden user ##[[KeyPgVirtual|Virtual]]## member procedure that will automatically launch the operator ##**Delete([])**## at derived-type level. + **Note:** Any operator ##**Delete[] Statement**## (or the only overload operator ##**Delete Statement**##) is not compatible with sub-type polymorphism, even using ##[[KeyPgOverride|Override]]## ##[[KeyPgVirtual|Virtual]]## ##[[KeyPgDestructor|Destructor]]## that may in addition induce crashing. + Instead of having to call such an operator ##**Delete([]) Statement**## on derived-type pointer, the safest way is to simply call (on base-type pointer) an overridden user ##[[KeyPgVirtual|Virtual]]## member procedure that will automatically launch the operator ##**Delete([]) Statement**## at derived-type level. {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/operator/delete.bas"}}%%(freebasic) @@ -70,7 +66,8 @@ p = 0 - New to ""FreeBASIC"" {{fbdoc item="see"}} - - ##[[KeyPgOpNew|New]]## + - ##[[KeyPgOpNew|New Expression]]## + - ##[[KeyPgOpDeleteOverload|Delete Overload]]## - ##[[KeyPgDeallocate|Deallocate]]## {{fbdoc item="back" value="CatPgOpMemory|Memory Operators"}}{{fbdoc item="back" value="CatPgOperators|Operators"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgOpLet.wakka b/doc/manual/cache/KeyPgOpLet.wakka index 6444d655dd..3feb0534ab 100644 --- a/doc/manual/cache/KeyPgOpLet.wakka +++ b/doc/manual/cache/KeyPgOpLet.wakka @@ -2,7 +2,7 @@ Indicates the assignment operator when overloading [[KeyPgOpAssignment|Operator = (Assignment)]] {{fbdoc item="syntax"}}## - { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] | [[KeyPgEnum|Enum]] } //typename// + { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] } //typename// [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **Let** ( [ [[KeyPgByref|byref]] | [[KeyPgByval|byval]] ] //rhs// [[KeyPgAs|as]] [[DataType|datatype]] ) End { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] } @@ -15,7 +15,7 @@ Indicates the assignment operator when overloading [[KeyPgOpAssignment|Operator ## {{fbdoc item="param"}} ##//typename//## - name of the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, ##[[KeyPgUnion|Union]]##, or ##[[KeyPgEnum|Enum]]## + name of the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgUnion|Union]]##. ##//lhs//## The variable to assign to. ##//rhs//## @@ -80,7 +80,7 @@ Thanks to the overloading operator Let (assign) - In the //[[CompilerOptlang|-lang qb]]// and //[[CompilerOptlang|-lang fblite]]// dialects, an assignment expression can be preceded by the ##[[KeyPgLet|Let]]## keyword. {{fbdoc item="diff"}} - - None + - None. {{fbdoc item="see"}} - ##[[KeyPgLet|Let]]## diff --git a/doc/manual/cache/KeyPgOpNew.wakka b/doc/manual/cache/KeyPgOpNew.wakka index 21858628b8..4ce5079ecd 100644 --- a/doc/manual/cache/KeyPgOpNew.wakka +++ b/doc/manual/cache/KeyPgOpNew.wakka @@ -1,10 +1,6 @@ -{{fbdoc item="title" value="Operator New"}}---- +{{fbdoc item="title" value="Operator New Expression"}}---- Operator to dynamically allocate memory and construct data of a specified type. -{{fbdoc item="syntax"}}## - [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **new** ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] - [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **new[]** ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] -## {{fbdoc item="usage"}}## //result// = **New** //[[DataType|datatype]]// //or// @@ -13,12 +9,10 @@ Operator to dynamically allocate memory and construct data of a specified type. //result// = **New** //[[DataType|datatype]]//**[** //count// **]** ## {{fbdoc item="param"}} - ##//size//## - Number of bytes to allocate. - ##//initializers//## - Initial value(s) for the variable. ##//datatype//## Name of the data type to create. + ##//initializers//## + Initial value(s) for the variable. ##//count//## Exact number of elements to allocate. @@ -26,19 +20,21 @@ Operator to dynamically allocate memory and construct data of a specified type. A pointer of type [[DataType|datatype]] to the newly allocated data. {{fbdoc item="desc"}} - The ##**New**## operator dynamically allocates memory and constructs a specified data type. + The ##**New Expression**## operator dynamically allocates memory and constructs a specified data type. For simple types, like integers, an initial value can be given. For types without constructors, initial values can be specified for each field (either with default initializer at data-field declaration, or with initializer list as in ##**New** //datatype// (**initializers, ..**)## if all type data-fields are numeric primitives only and without any default initializers). For types with at least one constructor, the initialize list (if any) must match an existing constructor. If no initializers are given, the default values for those types will be set. - ##**New[]**## is the array-version of the ##**New**## operator and allocates enough memory for the specified number of objects. The default constructor for the type will be used to set the initial values for each item. + ##**New[] Expression**## operator is the array-version of the ##**New Expression**## operator and allocates enough memory for the specified number of objects. The default constructor for the type will be used to set the initial values for each item. - Objects created with ##**New**## must be freed with ##[[KeyPgOpDelete|Delete]]##. Memory allocated with ##**New[]**## must be freed with ##**Delete[]**##, the array-version of ##[[KeyPgOpDelete|Delete]]##. You cannot mix and match the different versions of the operators. + Objects created with ##**New Expression**## operator must be freed with ##[[KeyPgOpDelete|Delete Statement]]## operator. Object array created with ##**New[] Expression**## operator must be freed with ##**Delete[] Statement**## operator, the array-version of ##[[KeyPgOpDelete|Delete Statement]]## operator. You cannot mix and match the different versions of the operators. Specifying an initial value of ##[[KeyPgAny|Any]]##, as in ##**New** //datatype// (**Any**)## will allocate memory for the type, but not initialize the data. This is only valid on data types that do not have constructors (otherwise for data types with constructors, syntax of simple memory allocation with pointer conversion, like //Cptr(datatype Ptr, Allocate(Sizeof(datatype)))//, can be substituted to the invalid use of New...Any). Specifying an initial value of ##[[KeyPgAny|Any]]##, as in ##**New** //datatype//[//count//] {**Any**}## will allocate memory for the array, but not initialize the data. This is only valid on data types that do not have constructors (otherwise for data types with constructors, syntax of simple memory allocation with pointer conversion, like //Cptr(datatype Ptr, Allocate(count * Sizeof(datatype)))//, can be substituted to the invalid use of New...Any). - This operator can be overloaded for user-defined types as a member ##[[KeyPgOperator|Operator]]##. + The dynamic memory allocation process part provided by the ##**New Expression**## operator can be overloaded for user-defined types as a member operator ##[[KeyPgOpNewOverload|New Overload]]##. The following process part for data construction can never be modified. + + **Note:** Using ##//pointer// = **New** //datatype//[//count//]## may be unsafe if ##//pointer//## was declared with a type different from ##//datatype//## (for sub-type polymorphism purpose for example), because the pointer arithmetic fails to access the elements if the pointer type size is different from the size of ##//datatype//## (when using ##{{fbdoc item="keyword" value="KeyPgOpPtrIndex|Operator [] (Pointer index)"}}## or adding an offset (element number) to the pointer, or even when ##**Delete[] Statement**## itself (the array-version of ##[[KeyPgOpDelete|Delete Statement]]##) must destroy the elements). {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/operator/new.bas"}}%%(freebasic) @@ -80,7 +76,8 @@ end scope - New to ""FreeBASIC"" {{fbdoc item="see"}} - - ##[[KeyPgOpDelete|Delete]]## + - ##[[KeyPgOpDelete|Delete Statement]]## - ##[[KeyPgOpPlacementNew|Placement New]]## + - ##[[KeyPgOpNewOverload|New Overload]]## {{fbdoc item="back" value="CatPgOpMemory|Memory Operators"}}{{fbdoc item="back" value="CatPgOperators|Operators"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgOpPlacementNew.wakka b/doc/manual/cache/KeyPgOpPlacementNew.wakka index c6834fd304..14fd3858d2 100644 --- a/doc/manual/cache/KeyPgOpPlacementNew.wakka +++ b/doc/manual/cache/KeyPgOpPlacementNew.wakka @@ -27,10 +27,14 @@ Operator to construct an object at a specified memory address. For simple types, like integers, an initial value can be given. For types without ##[[KeyPgConstructor|constructor]]##s, initial values can be specified for each field (either with default initializer at data-field declaration, or with initializer list as in ##**New** //datatype// (**initializers, ..**)## if all type data-fields are numeric primitives only and without any default initializers). For types with at least one constructor, the initialize list (if any) must match an existing constructor. If no initializers are given, the default values for those types will be set. Memory is **not** allocated when using the ##**Placement New**## operator. Instead, the memory at the specified ##//address//## is used (the provided memory size must be large enough to contain all the placement). - It is incorrect to call ##[[KeyPgOpDelete|Delete]]## on the address. The proper way is to only call the destructor if one exists (implicitly or explicitly), with syntax as for a member method by using member access operator. - See examples below for proper //placement new// usage. + It is incorrect to call ##[[KeyPgOpDelete|Delete Statement]]## on the address. The proper way is to only call the destructor if one exists (implicitly or explicitly), with syntax as for a member method by using member access operator. + See examples below for proper ##**Placement New**## operator usage. Specifying an initial value of ##[[KeyPgAny|Any]]##, as in ##**New**(//address//)//datatype// (**Any**)## or ##**New**(//address//)//datatype//[//count//] {**Any**}## will not initialize the data. This is only valid on data types that do not have constructors (otherwise for data types with constructors, syntax of simple pointer conversion, like //Cptr(datatype Ptr, address)//, can be substituted to the invalid use of New...Any). + + Because it does not provide any dynamic memory allocation process, the ##**Placement New**## operator (unlike the ##[[KeyPgOpNew|New Expression]]## operator) does not allow any overloading by a member operator for user-defined types. + + **Note:** Using ##//pointer// = **New**(//address//)//datatype//[//count//]## may be unsafe if ##//pointer//## was declared with a type different from ##//datatype//## (for sub-type polymorphism purpose for example), because the pointer arithmetic fails to access the elements if the pointer type size is different from the size of ##//datatype//## (when using ##{{fbdoc item="keyword" value="KeyPgOpPtrIndex|Operator [] (Pointer index)"}}## or adding an offset (element number) to the pointer). {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/operator/placement_new.bas"}}%%(freebasic) @@ -79,6 +83,6 @@ End Scope {{fbdoc item="see"}} - ##[[KeyPgDestructor|Destructor]]## - - ##[[KeyPgOpNew|New]]## + - ##[[KeyPgOpNew|New Expression]]## {{fbdoc item="back" value="CatPgOpMemory|Memory Operators"}}{{fbdoc item="back" value="CatPgOperators|Operators"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgOperator.wakka b/doc/manual/cache/KeyPgOperator.wakka index 0e5898e4ba..60a562a34c 100644 --- a/doc/manual/cache/KeyPgOperator.wakka +++ b/doc/manual/cache/KeyPgOperator.wakka @@ -2,16 +2,16 @@ Declares or defines an overloaded operator. {{fbdoc item="syntax"}}## - { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] | [[KeyPgEnum|Enum]] } //typename// + { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] } //typename// [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpCast|cast]] () [ [[KeyPgByrefFunction|byref]] ] [[KeyPgAs|as]] [[DataType|datatype]] [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpAt|@]] () [ [[KeyPgByrefFunction|byref]] ] [[KeyPgAs|as]] [[DataType|datatype]] [[KeyPgPtr|ptr]] [[KeyPgDeclare|declare]] **Operator** //assignment_op// ( [ [[KeyPgByref|byref]] | [[KeyPgByval|byval]] ] //rhs// [[KeyPgAs|as]] [[DataType|datatype]] ) [[KeyPgDeclare|declare]] **Operator** {{fbdoc item="keyword" value="KeyPgOpPtrIndex|[]"}} ( //index// [[KeyPgAs|as]] [[DataType|datatype]] ) [ [[KeyPgByrefFunction|byref]] ] [[KeyPgAs|as]] [[DataType|datatype]] - [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpNew|new]] ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] - [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpNew|new]][] ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] - [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpDelete|delete]] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) - [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpDelete|delete]][] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) - End { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] | [[KeyPgEnum|Enum]] } + [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpNewOverload|new]] ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] + [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpNewOverload|new]][] ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] + [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpDeleteOverload|delete]] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) + [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpDeleteOverload|delete]][] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) + End { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] } { [[KeyPgType|Type]] | [[KeyPgClass|Class]] | [[KeyPgUnion|Union]] } //typename// [[KeyPgDeclare|declare]] **Operator** [[KeyPgOpFor|For]] () @@ -31,10 +31,10 @@ Declares or defines an overloaded operator. **Operator** {{fbdoc item="keyword" value="KeyPgOpPtrIndex|[]"}} ( //index// [[KeyPgAs|as]] [[DataType|datatype]] ) [ [[KeyPgByrefFunction|byref]] ] [[KeyPgAs|as]] [[DataType|datatype]] [ [[KeyPgExport|Export]] ] **Operator** //unary_op// ( [ [[KeyPgByref|byref]] | [[KeyPgByval|byval]] ] //rhs// [[KeyPgAs|as]] [[DataType|datatype]] ) [[KeyPgAs|as]] [[DataType|datatype]] [ [[KeyPgExport|Export]] ] **Operator** //binary_op// ( [ [[KeyPgByref|byref]] | [[KeyPgByval|byval]] ] //lhs// [[KeyPgAs|as]] [[DataType|datatype]], [ [[KeyPgByref|byref]] | [[KeyPgByval|byval]] ] //rhs// [[KeyPgAs|as]] [[DataType|datatype]] ) [[KeyPgAs|as]] [[DataType|datatype]] [ [[KeyPgExport|Export]] ] - **Operator** //typename//.[[KeyPgOpNew|new]] ( //size// as uinteger ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] [ [[KeyPgExport|Export]] ] - **Operator** //typename//.[[KeyPgOpNew|new]][] ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] [ [[KeyPgExport|Export]] ] - **Operator** //typename//.[[KeyPgOpDelete|delete]] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) [ [[KeyPgExport|Export]] ] - **Operator** //typename//.[[KeyPgOpDelete|delete]][] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) [ [[KeyPgExport|Export]] ] + **Operator** //typename//.[[KeyPgOpNewOverload|new]] ( //size// as uinteger ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] [ [[KeyPgExport|Export]] ] + **Operator** //typename//.[[KeyPgOpNewOverload|new]][] ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] [ [[KeyPgExport|Export]] ] + **Operator** //typename//.[[KeyPgOpDeleteOverload|delete]] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) [ [[KeyPgExport|Export]] ] + **Operator** //typename//.[[KeyPgOpDeleteOverload|delete]][] ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) [ [[KeyPgExport|Export]] ] ## {{fbdoc item="param"}} ##//typename//## @@ -51,21 +51,21 @@ Declares or defines an overloaded operator. {{fbdoc item="desc"}} The built in operators like ##=##, ##+##, and ##cast## have predefined behaviors when used in expressions. These operators can be overloaded to do something other than predefined operations when at least one of the arguments to the operator is a ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, ##[[KeyPgEnum|Enum]]##, or ##[[KeyPgUnion|Union]]## data type. - Operators are just functions. The operator '+' has functionality like ##Function Plus( A as DataType, B as DataType ) as DataType##. See //[[ProPgOperatorOverloading|Operator Overloading]]// for more information. Operators can be overloaded to accept different data types as parameters. The ##[[KeyPgOpCast|Cast]]## Operator is the only operator (or function) that can be declared multiple times when only the return type differs, but not the same as the ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]## it is declared in (for not explicit usage, the compiler may decide which cast overload to call based on how the object is used). + Operators are just functions. The operator '+' has functionality like ##Function Plus( A as DataType, B as DataType ) as DataType##. See //[[ProPgOperatorOverloading|Operator Overloading]]// for more information. Operators can be overloaded to accept different data types as parameters. The ##[[KeyPgOpCast|Cast]]## Operator is the only operator (or function) that can be declared multiple times when only the return type differs, but not the same as the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgUnion|Union]]## it is declared in (for not explicit usage, the compiler may decide which cast overload to call based on how the object is used). - Non-static operator members are declared inside the ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]##. Global operators are declared outside. All operator definitions (procedure bodies) must appear outside. + Non-static operator members are declared inside the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgUnion|Union]]##. Global operators are declared outside. All operator definitions (procedure bodies) must appear outside. - ##**Let**##, ##**Cast**##, and other assignment operators must be declared inside the ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]##. As all non-static member procedures, they have passed a hidden ##[[KeyPgThis|this]]## parameter. + ##**Let**##, ##**Cast**##, and other assignment operators must be declared inside the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgUnion|Union]]##. As all non-static member procedures, they have passed a hidden ##[[KeyPgThis|this]]## parameter. - Unary operators must be declared outside the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgEnum|Enum]]## and have a return data type explicitly declared. Unary operators can be overloaded to return any valid data type, except for ##[[KeyPgOpPtrMemberAccess|Operator -> (Pointer to member access)]]## which must return a ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]## data type. + Unary operators must be declared outside the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgUnion|Union]]## and have a return data type explicitly declared. Unary operators can be overloaded to return any valid data type, except for ##[[KeyPgOpPtrMemberAccess|Operator -> (Pointer to member access)]]## which must return a ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgUnion|Union]]## data type. - Binary operators must be declared outside the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgEnum|Enum]]## and have a return data type explicitly declared. Binary operators can be overloaded with valid data types, including for relational operators, which can also return any valid data type. + Binary operators must be declared outside the ##[[KeyPgType|Type]]##, ##[[KeyPgClass|Class]]##, or ##[[KeyPgUnion|Union]]## and have a return data type explicitly declared. Binary operators can be overloaded with valid data types, including for relational operators, which can also return any valid data type. ##[[KeyPgLet|Let]]## refers to the assignment operator, as in ##LET a=b##. The ##[[KeyPgLet|Let]]## keyword is omitted in common practice, and is not allowed in the //[[CompilerOptlang|-lang fb]]// dialect. However, ##[[KeyPgOpLetlist|Let()]]## can be used to assign the fields of a UDT to multiple variables. See ##[[KeyPgOpFor|For]]##, ##[[KeyPgOpStep|Step]]##, and ##[[KeyPgOpNext|Next]]## for more information on overloading the ##[[KeyPgFornext|For..Next]]## statement for use with user defined types. - ##**New**##, ##**New[]**##, ##**Delete**##, and ##**Delete[]**## operator members are always static, even if not explicitly declared (##[[KeyPgStaticMember|static]]## keyword is unnecessary but allowed). + Member operators ##**New**##, ##**New[]**##, ##**Delete**##, and ##**Delete[]**## are always static, even if not explicitly declared (##[[KeyPgStaticMember|static]]## keyword is unnecessary but allowed). {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/udt/operator1.bas"}}%%(freebasic) @@ -117,67 +117,6 @@ c *= 3 Print "c = "; c, "abs(c) ="; Abs( c ) %% - Aligned memory allocator: - - by using the overloaded member operators "New" and "Delete", any created User object is aligned to a multiple of "ALIGN" bytes (256 bytes in this example), - - the real pointer of the allocated memory is saved just above the User pointer, in the padding block. -{{fbdoc item="filename" value="examples/manual/udt/operator2.bas"}}%%(freebasic) -'' operator2.bas - -Const ALIGN = 256 - -Type UDT - Dim As Byte a(0 to 10 * 1024 * 1024 - 1) '' 10 megabyte fixed array - Declare Operator New (Byval size As UInteger) As Any Ptr - Declare Operator Delete (Byval buffer As Any Ptr) - Declare Constructor () - Declare Destructor () -End Type - -Operator UDT.New (Byval size As UInteger) As Any Ptr - Print " Overloaded New operator, with parameter size = &h" & Hex(size) - Dim pOrig As Any Ptr = Callocate(ALIGN-1 + Sizeof(UDT Ptr) + size) - Dim pMin As Any Ptr = pOrig + Sizeof(UDT Ptr) - Dim p As Any Ptr = pMin + ALIGN-1 - (Culng(pMin + ALIGN-1) Mod ALIGN) - Cast(Any Ptr Ptr, p)[-1] = pOrig - Operator = p - Print " real pointer = &h" & Hex(pOrig), "return pointer = &h" & Hex(p) -End Operator - -Operator UDT.Delete (Byval buffer As Any Ptr) - Print " Overloaded Delete operator, with parameter buffer = &h" & Hex(buffer) - Dim pOrig As Any Ptr = Cast(Any Ptr Ptr, buffer)[-1] - Deallocate(pOrig) - Print " real pointer = &h" & Hex(pOrig) -End Operator - -Constructor UDT () - Print " Constructor, @This = &h" & Hex(@This) -End Constructor - -Destructor UDT () - Print " Destructor, @This = &h" & Hex(@This) -End destructor - -Print "'Dim As UDT Ptr p = New UDT'" -Dim As UDT Ptr p = New UDT - -Print " p = &h" & Hex(p) - -Print "'Delete p'" -Delete p -%% - Output example: - %% -'Dim As UDT Ptr p = New UDT' - Overloaded New operator, with parameter size = &hA00000 - real pointer = &h420020 return pointer = &h420100 - Constructor, @This = &h420100 - p = &h420100 -'Delete p' - Destructor, @This = &h420100 - Overloaded Delete operator, with parameter buffer = &h420100 - real pointer = &h420020 -%% Small use case of the operator "[]": simplest smart pointers for byte buffers. {{fbdoc item="filename" value="examples/manual/udt/operator3.bas"}}%%(freebasic) '' operator3.bas @@ -242,7 +181,7 @@ End Scope {{fbdoc item="see"}} - ##[[KeyPgClass|Class]]## - - ##[[KeyPgEnum|Enum]]## + - ##[[KeyPgUnion|Union]]## - ##[[KeyPgType|Type]]## - [[ProPgDataConversion|Coercion and Conversion]] diff --git a/doc/manual/cache/KeyPgPragma.wakka b/doc/manual/cache/KeyPgPragma.wakka index 5a27c4dc43..51a4abff38 100644 --- a/doc/manual/cache/KeyPgPragma.wakka +++ b/doc/manual/cache/KeyPgPragma.wakka @@ -11,7 +11,7 @@ Preprocessor directive {{fbdoc item="param"}} Possible values for ##//option//## and related ##//value//##s: - {{table columns="3" cellpadding="1" cells="Option; Value; Description; msbitfields; 0; Use bitfields compatible with gcc (default);###; -1 (or any other non-zero value); Use bitfields compatible with those used in Microsoft C compilers; once; N/A; cause the source file in which the pragma appears to behave as though it was included with #include once ..."}} + {{table columns="3" cellpadding="1" cells="Option; Value; Description; msbitfields; 0; Use bitfields compatible with gcc (default);###; -1 (or any other non-zero value); Use bitfields compatible with those used in Microsoft C compilers; once; N/A; cause the source file in which the pragma appears to behave as though it was included with #include once ...; constness; 0; cause the source file in which the pragma appears to disable 'CONST qualifier discarded' warning;###; -1 (or any other non-zero value); cause the source file in which the pragma appears to enable 'CONST qualifier discarded' warning"}} If //value// is not given, the compiler assumes //-1// (//TRUE//). diff --git a/doc/manual/cache/PrintToc.wakka b/doc/manual/cache/PrintToc.wakka index 93099fd3ee..444608b74c 100644 --- a/doc/manual/cache/PrintToc.wakka +++ b/doc/manual/cache/PrintToc.wakka @@ -210,7 +210,7 @@ [[KeyPgDefuint|DEFUINT]] [[KeyPgDefulongint|DEFULONGINT]] [[KeyPgDefushort|DEFUSHORT]] - [[KeyPgOpDelete|DELETE]] + [[KeyPgOpDelete|DELETE (Statement)]] [[KeyPgDestructor|DESTRUCTOR]] [[KeyPgModuleDestructor|DESTRUCTOR (Module)]] [[KeyPgDim|DIM]] @@ -364,7 +364,7 @@ [[KeyPgNaked|NAKED]] [[KeyPgName|NAME]] [[KeyPgNamespace|NAMESPACE]] - [[KeyPgOpNew|NEW]] + [[KeyPgOpNew|NEW (Expression)]] [[KeyPgOpPlacementNew|NEW (Placement)]] [[KeyPgNext|NEXT]] [[KeyPgResumenext|NEXT (RESUME)]] @@ -692,9 +692,11 @@ [[KeyPgOpIs|Operator Is (Run-time type information)]] {{fbdoc item="subsect" value="Memory operators"}} - [[KeyPgOpNew|Operator New]] + [[KeyPgOpNew|Operator New Expression]] + [[KeyPgOpNewOverload|Operator New Overload]] [[KeyPgOpPlacementNew|Operator Placement New]] - [[KeyPgOpDelete|Operator Delete]] + [[KeyPgOpDelete|Operator Delete Statement]] + [[KeyPgOpDeleteOverload|Operator Delete Overload]] {{fbdoc item="subsect" value="Iterating operators"}} [[KeyPgOpFor|Operator For]] diff --git a/doc/manual/cache/ProPgCtorsDtors.wakka b/doc/manual/cache/ProPgCtorsDtors.wakka index b59b2da20d..3fe11f263c 100644 --- a/doc/manual/cache/ProPgCtorsDtors.wakka +++ b/doc/manual/cache/ProPgCtorsDtors.wakka @@ -10,7 +10,7 @@ In charge of the creation and destruction of objects. {{anchor name="OVERVIEW"}}{{fbdoc item="section" value="Overview"}} Constructors and destructors are responsible for creating and destroying objects, respectively. In general, constructors give objects their initial state, that is, they give meaningful values to their objects' member data. Destructors perform the opposite function; they make sure any resources owned by their objects are properly freed. - Simply, constructors are special member procedures that are called when an object is created, and destructors are special member procedures called when an object is destroyed. Both constructors and destructors are called automatically by the compiler whenever an object is created or destroyed, whether explicitly with the use of the ##[[KeyPgDim|Dim]]## or ##[[KeyPgOpNew|New]]##/##[[KeyPgOpDelete|Delete]]## keywords, or implicitly by passing an object to a procedure by value or through an object going out of scope. + Simply, constructors are special member procedures that are called when an object is created, and destructors are special member procedures called when an object is destroyed. Both constructors and destructors are called automatically by the compiler whenever an object is created or destroyed, whether explicitly with the use of the ##[[KeyPgDim|Dim]]## or ##[[KeyPgOpNew|New Expression]]##/##[[KeyPgOpDelete|Delete Statement]]## keywords, or implicitly by passing an object to a procedure by value or through an object going out of scope. {{anchor name="DECLARATION"}}{{fbdoc item="section" value="Declaration"}} Constructors and destructors are declared like member procedures but with the ##[[KeyPgConstructor|Constructor]]## keyword instead of ##[[KeyPgMemberSub|Sub]]## or ##[[KeyPgMemberFunction|Function]]##, and without a name. Similarly, they are defined with only the name of the ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]## they are declared in. @@ -18,7 +18,7 @@ In charge of the creation and destruction of objects. A ##[[KeyPgType|Type]]## or ##[[KeyPgClass|Class]]## can have multiple constructors, but only one destructor. {{anchor name="DEFCTOR"}}{{fbdoc item="section" value="Default constructors"}} - Default constructors are constructors that either have no parameters, or all of their parameters have a default value. They are called when an object is defined but not initialized, or is created as part of an array, with the ##[[KeyPgDim|Dim]]##, ##[[KeyPgRedim|Redim]]## or ##[[KeyPgOpNew|New]]##[] keywords. The first constructor declared in the example below is a default constructor. + Default constructors are constructors that either have no parameters, or all of their parameters have a default value. They are called when an object is defined but not initialized, or is created as part of an array, with the ##[[KeyPgDim|Dim]]##, ##[[KeyPgRedim|Redim]]## or ##[[KeyPgOpNew|New]]##[] expression keywords. The first constructor declared in the example below is a default constructor. {{anchor name="COPYCTOR"}}{{fbdoc item="section" value="Copy constructors"}} Copy constructors are constructors called when an object is created, or cloned, from another object of the same type (or an object that can be converted to that type). This happens explicitly when initializing an object with another object, or implicitly by passing an object to a procedure by value. Copy constructors are declared having one parameter: an object of the same type passed by reference. @@ -26,7 +26,7 @@ In charge of the creation and destruction of objects. Copy constructors are only called when creating and initializing object instances. Assignment to objects is handled by the ##[[KeyPgOperator|member operator let]]##. {{anchor name="CALLCTOR"}}{{fbdoc item="section" value="Calling constructors"}} - Unlike other member procedures, constructors are generally not called directly from an object instance. Instead, a constructor is specified in a ##[[KeyPgDim|Dim]]## statement either with an initializer or without one, or in a ##[[KeyPgOpNew|New]]## statement with or without arguments. + Unlike other member procedures, constructors are generally not called directly from an object instance. Instead, a constructor is specified in a ##[[KeyPgDim|Dim]]## statement either with an initializer or without one, or in a ##[[KeyPgOpNew|New Expression]]## statement with or without arguments. When specifying an initializer for an object, the name of the type followed by any arguments it requires is used. From 5d1ac76daebc811f976915bb70eb0a20940fff8e Mon Sep 17 00:00:00 2001 From: coderJeff Date: Mon, 3 Sep 2018 10:44:01 -0400 Subject: [PATCH 4/7] fbdoc: wiki snapshot 2018-09-03 --- doc/manual/cache/CatPgFullIndex.wakka | 2 + doc/manual/cache/CatPgFunctIndex.wakka | 2 + doc/manual/cache/CompilerErrMsg.wakka | 575 ++++++++++--------- doc/manual/cache/KeyPgFunctionPtr.wakka | 4 +- doc/manual/cache/KeyPgOpDeleteOverload.wakka | 36 ++ doc/manual/cache/KeyPgOpNewOverload.wakka | 302 ++++++++++ doc/manual/cache/KeyPgSubPtr.wakka | 4 +- doc/manual/cache/PrintToc.wakka | 10 +- 8 files changed, 643 insertions(+), 292 deletions(-) create mode 100644 doc/manual/cache/KeyPgOpDeleteOverload.wakka create mode 100644 doc/manual/cache/KeyPgOpNewOverload.wakka diff --git a/doc/manual/cache/CatPgFullIndex.wakka b/doc/manual/cache/CatPgFullIndex.wakka index 21e48bdcfb..35d3248b6e 100644 --- a/doc/manual/cache/CatPgFullIndex.wakka +++ b/doc/manual/cache/CatPgFullIndex.wakka @@ -273,6 +273,7 @@ Alphabetical listing of keywords, macros and procedures. - {{fbdoc item="keyword" value="KeyPgFreefile|FREEFILE"}} - {{fbdoc item="keyword" value="KeyPgFunction|FUNCTION"}} - {{fbdoc item="keyword" value="KeyPgMemberFunction|FUNCTION (Member)"}} + - {{fbdoc item="keyword" value="KeyPgFunctionPtr|FUNCTION (Pointer)"}} {{fbdoc item="section" value="G"}}{{anchor name="g"}} - {{fbdoc item="keyword" value="KeyPgGetgraphics|GET (Graphics)"}} @@ -516,6 +517,7 @@ Alphabetical listing of keywords, macros and procedures. - {{fbdoc item="keyword" value="KeyPgOpStrptr|STRPTR"}} - {{fbdoc item="keyword" value="KeyPgSub|SUB"}} - {{fbdoc item="keyword" value="KeyPgMemberSub|SUB (Member)"}} + - {{fbdoc item="keyword" value="KeyPgSubPtr|SUB (Pointer)"}} - {{fbdoc item="keyword" value="KeyPgSwap|SWAP"}} - {{fbdoc item="keyword" value="KeyPgSystem|SYSTEM"}} diff --git a/doc/manual/cache/CatPgFunctIndex.wakka b/doc/manual/cache/CatPgFunctIndex.wakka index 63f9e02d62..fe7460f7cc 100644 --- a/doc/manual/cache/CatPgFunctIndex.wakka +++ b/doc/manual/cache/CatPgFunctIndex.wakka @@ -74,6 +74,7 @@ List of ""FreeBASIC"" keywords sorted by the function they perform. - {{fbdoc item="keyword" value="KeyPgDouble|DOUBLE"}} - {{fbdoc item="keyword" value="KeyPgEnum|ENUM"}} - {{fbdoc item="keyword" value="KeyPgExtends|EXTENDS"}} + - {{fbdoc item="keyword" value="KeyPgFunctionPtr|FUNCTION (Pointer)"}} - {{fbdoc item="keyword" value="KeyPgImplements|IMPLEMENTS"}} - {{fbdoc item="keyword" value="KeyPgInteger|INTEGER"}} - {{fbdoc item="keyword" value="KeyPgLong|LONG"}} @@ -85,6 +86,7 @@ List of ""FreeBASIC"" keywords sorted by the function they perform. - {{fbdoc item="keyword" value="KeyPgSingle|SINGLE"}} - {{fbdoc item="keyword" value="KeyPgStatic|STATIC"}} - {{fbdoc item="keyword" value="KeyPgString|STRING"}} + - {{fbdoc item="keyword" value="KeyPgSubPtr|SUB (Pointer)"}} - {{fbdoc item="keyword" value="KeyPgType|TYPE"}} - {{fbdoc item="keyword" value="KeyPgTypeAlias|TYPE (Alias)"}} - {{fbdoc item="keyword" value="KeyPgTypeTemp|TYPE (Temporary)"}} diff --git a/doc/manual/cache/CompilerErrMsg.wakka b/doc/manual/cache/CompilerErrMsg.wakka index 1d0f025419..452c49d250 100644 --- a/doc/manual/cache/CompilerErrMsg.wakka +++ b/doc/manual/cache/CompilerErrMsg.wakka @@ -42,8 +42,12 @@ During the program compilation three types of errors can arise: - //35 Mixing signed/unsigned operands// - //36 Mismatching parameter initializer// - //37 // - - //38 Mixing operand data types may have undefined results// + - //38 Suspicious logic operation, mixed boolean and non-boolean operands// - //39 Redefinition of intrinsic// + - //40 CONST qualifier discarded// + - //41 Return type mismatch// + - //42 Calling convention mismatch// + - //43 Argument count mismatch// ==Compiler Error messages:== The error messages stop the compilation after 10 errors (see the -maxerr command-line option to change that default value) or a fatal error occurred, and require a correction by the user before the compilation can be continued. The compiler signals the lines where the errors have been found, so the correction can be done quickly. In a few cases the place pointed at by the error messages is not where the errors can be found, it's the place where the compiler has given up in waiting for something that should be somewhere. @@ -87,290 +91,291 @@ During the program compilation three types of errors can arise: - //37 Array boundaries do not match the original EXTERN declaration// - //38 'SUB' or 'FUNCTION' without 'END SUB' or 'END FUNCTION'// - //39 Expected 'END SUB' or 'END FUNCTION'// - - //40 Illegal parameter specification// - - //41 Variable not declared// - - //42 Variable required// - - //43 Illegal outside a compound statement// - - //44 Expected 'END ASM'// - - //45 Function not declared// - - //46 Expected ';'// - - //47 Undefined label// - - //48 Too many array dimensions// - - //49 Array too big// - - //50 User Defined Type too big// - - //51 Expected scalar counter// - - //52 Illegal outside a CONSTRUCTOR, DESTRUCTOR, FUNCTION, OPERATOR, PROPERTY or SUB block// - - //53 Expected var-len array// - - //54 Fixed-len strings cannot be returned from functions// - - //55 Array already dimensioned// - - //56 Illegal without the -ex option// - - //57 Type mismatch// - - //58 Illegal specification// - - //59 Expected 'END WITH'// - - //60 Illegal inside functions// - - //61 Statement in between SELECT and first CASE// - - //62 Expected array// - - //63 Expected '{'// - - //64 Expected '}'// - - //65 Expected ']'// - - //66 Too many expressions// - - //67 Expected explicit result type// - - //68 Range too large// - - //69 Forward references not allowed// - - //70 Incomplete type// - - //71 Array not dimensioned// - - //72 Array access, index expected// - - //73 Expected 'END ENUM'// - - //74 Var-len arrays cannot be initialized// - - //75 '...' ellipsis upper bound given for dynamic array (this is not supported)// - - //76 '...' ellipsis upper bound given for array field (this is not supported)// - - //77 Invalid bitfield// - - //78 Too many parameters// - - //79 Macro text too long// - - //80 Invalid command-line option// - - //81 Selected non-x86 CPU when compiling for DOS// - - //82 Selected -gen gas ASM backend for non-x86 CPU// - - //83 -asm att used for -gen gas, but -gen gas only supports -asm intel// - - //84 -pic used when making executable (only works when making a shared library)// - - //85 -pic used, but not supported by target system (only works for non-x86 Unixes)// - - //86 Var-len strings cannot be initialized// - - //87 Recursive TYPE or UNION not allowed// - - //88 Recursive DEFINE not allowed// - - //89 Identifier cannot include periods// - - //90 Executable not found// - - //91 Array out-of-bounds// - - //92 Missing command-line option for// - - //93 Expected 'ANY'// - - //94 Expected 'END SCOPE'// - - //95 Illegal inside a compound statement or scoped block// - - //96 UDT function results cannot be passed by reference// - - //97 Ambiguous call to overloaded function// - - //98 No matching overloaded function// - - //99 Division by zero// - - //100 Cannot pop stack, underflow// - - //101 UDT's containing var-len string fields cannot be initialized// - - //102 Branching to scope block containing local variables// - - //103 Branching to other functions or to module-level// - - //104 Branch crossing local array, var-len string or object definition// - - //105 LOOP without DO// - - //106 NEXT without FOR// - - //107 WEND without WHILE// - - //108 END WITH without WITH// - - //109 END IF without IF// - - //110 END SELECT without SELECT// - - //111 END SUB or FUNCTION without SUB or FUNCTION// - - //112 END SCOPE without SCOPE// - - //113 END NAMESPACE without NAMESPACE// - - //114 END EXTERN without EXTERN// - - //115 ELSEIF without IF// - - //116 ELSE without IF// - - //117 CASE without SELECT// - - //118 Cannot modify a constant// - - //119 Expected period ('.')// - - //120 Expected 'END NAMESPACE'// - - //121 Illegal inside a NAMESPACE block// - - //122 Symbols defined inside namespaces cannot be removed// - - //123 Expected 'END EXTERN'// - - //124 Expected 'END SUB'// - - //125 Expected 'END FUNCTION'// - - //126 Expected 'END CONSTRUCTOR'// - - //127 Expected 'END DESTRUCTOR'// - - //128 Expected 'END OPERATOR'// - - //129 Expected 'END PROPERTY'// - - //130 Declaration outside the original namespace// - - //131 No end of multi-line comment, expected "'/"// - - //132 Too many errors, exiting// - - //133 Expected 'ENDMACRO'// - - //134 EXTERN or COMMON variables cannot be initialized// - - //135 EXTERN or COMMON dynamic arrays cannot have initial bounds// - - //136 At least one parameter must be a user-defined type// - - //137 Parameter or result must be a user-defined type// - - //138 Both parameters can't be of the same type// - - //139 Parameter and result can't be of the same type// - - //140 Invalid result type for this operator// - - //141 Invalid parameter type, it must be the same as the parent TYPE/CLASS// - - //142 Vararg parameters are not allowed in overloaded functions// - - //143 Illegal outside an OPERATOR block// - - //144 Parameter cannot be optional// - - //145 Only valid in -lang// - - //146 Default types or suffixes are only valid in -lang// - - //147 Suffixes are only valid in -lang// - - //148 Implicit variables are only valid in -lang// - - //149 Auto variables are only valid in -lang// - - //150 Invalid array index// - - //151 Operator must be a member function// - - //152 Operator cannot be a member function// - - //153 Method declared in anonymous UDT// - - //154 Constant declared in anonymous UDT// - - //155 Static variable declared in anonymous UDT// - - //156 Expected operator// - - //157 Declaration outside the original namespace or class// - - //158 A destructor should not have any parameters// - - //159 Expected class or UDT identifier// - - //160 Var-len strings cannot be part of UNION's or nested TYPE's// - - //161 Dynamic arrays cannot be part of UNION's or nested TYPE's// - - //162 Fields with constructors cannot be part of UNION's or nested TYPE's// - - //163 Fields with destructors cannot be part of UNION's or nested TYPE's// - - //164 Illegal outside a CONSTRUCTOR block// - - //165 Illegal outside a DESTRUCTOR block// - - //166 UDT's with methods must have unique names// - - //167 Parent is not a class or UDT// - - //168 CONSTRUCTOR() chain call not at top of constructor// - - //169 BASE() initializer not at top of constructor// - - //170 REDIM on UDT with non-CDECL constructor// - - //171 REDIM on UDT with non-CDECL destructor// - - //172 REDIM on UDT with non-parameterless default constructor// - - //173 ERASE on UDT with non-CDECL constructor// - - //174 ERASE on UDT with non-CDECL destructor// - - //175 ERASE on UDT with non-parameterless default constructor// - - //176 This symbol cannot be undefined// - - //177 RETURN mixed with 'FUNCTION =' or EXIT FUNCTION (using both styles together is unsupported when returning objects with constructors)// - - //178 'FUNCTION =' or EXIT FUNCTION mixed with RETURN (using both styles together is unsupported when returning objects with constructors)// - - //179 Missing RETURN to copy-construct function result// - - //180 Invalid assignment/conversion// - - //181 Invalid array subscript// - - //182 TYPE or CLASS has no default constructor// - - //183 Function result TYPE has no default constructor// - - //184 Missing BASE() initializer (base UDT without default constructor requires manual initialization)// - - //185 Missing default constructor implementation (base UDT without default constructor requires manual initialization)// - - //186 Missing UDT.constructor(byref as UDT) implementation (base UDT without default constructor requires manual initialization)// - - //187 Missing UDT.constructor(byref as const UDT) implementation (base UDT without default constructor requires manual initialization)// - - //188 Invalid priority attribute// - - //189 PROPERTY GET should have no parameter, or just one if indexed// - - //190 PROPERTY SET should have one parameter, or just two if indexed// - - //191 Expected 'PROPERTY'// - - //192 Illegal outside a PROPERTY block// - - //193 PROPERTY has no GET method/accessor// - - //194 PROPERTY has no SET method/accessor// - - //195 PROPERTY has no indexed GET method/accessor// - - //196 PROPERTY has no indexed SET method/accessor// - - //197 Missing overloaded operator: // - - //198 The NEW[] operator does not allow explicit calls to constructors// - - //199 The NEW[] operator only supports the { ANY } initialization// - - //200 The NEW operator cannot be used with fixed-length strings// - - //201 Illegal member access// - - //202 Expected ':'// - - //203 The default constructor has no public access// - - //204 Constructor has no public access// - - //205 Destructor has no public access// - - //206 Accessing base UDT's private default constructor// - - //207 Accessing base UDT's private destructor// - - //208 Illegal non-static member access// - - //209 Constructor declared ABSTRACT// - - //210 Constructor declared VIRTUAL// - - //211 Destructor declared ABSTRACT// - - //212 Member cannot be static// - - //213 Member isn't static// - - //214 Only static members can be accessed from static functions// - - //215 The PRIVATE and PUBLIC attributes are not allowed with REDIM, COMMON or EXTERN// - - //216 STATIC used here, but not the in the DECLARE statement// - - //217 CONST used here, but not the in the DECLARE statement// - - //218 VIRTUAL used here, but not the in the DECLARE statement// - - //219 ABSTRACT used here, but not the in the DECLARE statement// - - //220 Method declared VIRTUAL, but UDT does not extend OBJECT// - - //221 Method declared ABSTRACT, but UDT does not extend OBJECT// - - //222 Not overriding any virtual method// - - //223 Implemented body for an ABSTRACT method// - - //224 Override has different return type than overridden method// - - //225 Override has different calling convention than overridden method// - - //226 Implicit destructor override would have different calling convention// - - //227 Implicit LET operator override would have different calling convention// - - //228 Override is not a CONST member like the overridden method// - - //229 Override is a CONST member, but the overridden method is not// - - //230 Override has different parameters than overridden method// - - //231 This operator cannot be STATIC// - - //232 This operator is implicitly STATIC and cannot be VIRTUAL or ABSTRACT// - - //233 This operator is implicitly STATIC and cannot be CONST// - - //234 Parameter must be an integer// - - //235 Parameter must be a pointer// - - //236 Expected initializer// - - //237 Fields cannot be named as keywords in TYPE's that contain member functions or in CLASS'es// - - //238 Illegal outside a FOR compound statement// - - //239 Illegal outside a DO compound statement// - - //240 Illegal outside a WHILE compound statement// - - //241 Illegal outside a SELECT compound statement// - - //242 Expected 'FOR'// - - //243 Expected 'DO'// - - //244 Expected 'WHILE'// - - //245 Expected 'SELECT'// - - //246 No outer FOR compound statement found// - - //247 No outer DO compound statement found// - - //248 No outer WHILE compound statement found// - - //249 No outer SELECT compound statement found// - - //250 Expected 'CONSTRUCTOR', 'DESTRUCTOR', 'DO', 'FOR', 'FUNCTION', 'OPERATOR', 'PROPERTY', 'SELECT', 'SUB' or 'WHILE'// - - //251 Expected 'DO', 'FOR' or 'WHILE'// - - //252 Illegal outside a SUB block// - - //253 Illegal outside a FUNCTION block// - - //254 Ambiguous symbol access, explicit scope resolution required// - - //255 An ENUM, TYPE or UNION cannot be empty// - - //256 ENUM's declared inside EXTERN .. END EXTERN blocks don't open new scopes// - - //257 STATIC used on non-member procedure// - - //258 CONST used on non-member procedure// - - //259 ABSTRACT used on non-member procedure// - - //260 VIRTUAL used on non-member procedure// - - //261 Invalid initializer// - - //262 Objects with default [con|de]structors or methods are only allowed in the module level// - - //263 Static member variable in nested UDT (only allowed in toplevel UDTs)// - - //264 Symbol not a CLASS, ENUM, TYPE or UNION type// - - //265 Too many elements// - - //266 Only data members supported// - - //267 UNIONs are not allowed// - - //268 Arrays are not allowed// - - //269 COMMON variables cannot be object instances of CLASS/TYPE's with cons/destructors// - - //270 Cloning operators (LET, Copy constructors) can't take a byval arg of the parent's type// - - //271 Local symbols can't be referenced// - - //272 Expected 'PTR' or 'POINTER'// - - //273 Too many levels of pointer indirection// - - //274 Dynamic arrays can't be const// - - //275 Const UDT cannot invoke non-const method// - - //276 Elements must be empty for strings and arrays// - - //277 GOSUB disabled, use 'OPTION GOSUB' to enable// - - //278 Invalid -lang// - - //279 Can't use ANY as initializer in array with ellipsis bound// - - //280 Must have initializer with array with ellipsis bound// - - //281 Can't use ... as lower bound// - - //282 FOR/NEXT variable name mismatch// - - //283 Selected option requires an SSE FPU mode// - - //284 Expected relational operator ( =, >, <, <>, <=, >= )// - - //285 Unsupported statement in -gen gcc mode// - - //286 Too many labels// - - //287 Unsupported function// - - //288 Expected sub// - - //289 Expected '#ENDIF'// - - //290 Resource file given for target system that does not support them// - - //291 -o option without corresponding input file// - - //292 Not extending a TYPE/UNION (a TYPE/UNION can only extend other TYPEs/UNIONs)// - - //293 Illegal outside a CLASS, TYPE or UNION method// - - //294 CLASS, TYPE or UNION not derived// - - //295 CLASS, TYPE or UNION has no constructor// - - //296 Symbol type has no Run-Time Type Info (RTTI)// - - //297 Types have no hierarchical relation// - - //298 Expected a CLASS, TYPE or UNION symbol type// - - //299 Casting derived UDT pointer from incompatible pointer type// - - //300 Casting derived UDT pointer from unrelated UDT pointer type// - - //301 Casting derived UDT pointer to incompatible pointer type// - - //302 Casting derived UDT pointer to unrelated UDT pointer type// - - //303 ALIAS name string is empty// - - //304 LIB name string is empty// - - //305 UDT has unimplemented abstract methods// - - //306 Non-virtual call to ABSTRACT method// - - //307 #ASSERT condition failed// - - //308 Expected '>'// - - //309 Invalid size// - - //310 ALIAS name here is different from ALIAS given in DECLARE prototype// - - //311 vararg parameters are only allowed in CDECL procedures// - - //312 the first parameter in a procedure may not be vararg// - - //313 CONST used on constructor (not needed)// - - //314 CONST used on destructor (not needed)// - - //315 Byref function result not set// - - //316 Function result assignment outside of the function// - - //317 Type mismatch in byref function result assignment// - - //318 -asm att|intel option given, but not supported for this target (only x86 or x86_64)// - - //319 Reference not initialized// - - //320 Incompatible reference initializer// - - //321 Array of references - not supported yet// - - //322 Invalid CASE range, start value is greater than the end value// - - //323 Fixed-length string combined with BYREF (not supported)// + - //40 Return type here does not match DECLARE prototype// + - //41 Calling convention does not match DECLARE prototype// + - //42 Variable not declared// + - //43 Variable required// + - //44 Illegal outside a compound statement// + - //45 Expected 'END ASM'// + - //46 Function not declared// + - //47 Expected ';'// + - //48 Undefined label// + - //49 Too many array dimensions// + - //50 Array too big// + - //51 User Defined Type too big// + - //52 Expected scalar counter// + - //53 Illegal outside a CONSTRUCTOR, DESTRUCTOR, FUNCTION, OPERATOR, PROPERTY or SUB block// + - //54 Expected var-len array// + - //55 Fixed-len strings cannot be returned from functions// + - //56 Array already dimensioned// + - //57 Illegal without the -ex option// + - //58 Type mismatch// + - //59 Illegal specification// + - //60 Expected 'END WITH'// + - //61 Illegal inside functions// + - //62 Statement in between SELECT and first CASE// + - //63 Expected array// + - //64 Expected '{'// + - //65 Expected '}'// + - //66 Expected ']'// + - //67 Too many expressions// + - //68 Expected explicit result type// + - //69 Range too large// + - //70 Forward references not allowed// + - //71 Incomplete type// + - //72 Array not dimensioned// + - //73 Array access, index expected// + - //74 Expected 'END ENUM'// + - //75 Var-len arrays cannot be initialized// + - //76 '...' ellipsis upper bound given for dynamic array (this is not supported)// + - //77 '...' ellipsis upper bound given for array field (this is not supported)// + - //78 Invalid bitfield// + - //79 Too many parameters// + - //80 Macro text too long// + - //81 Invalid command-line option// + - //82 Selected non-x86 CPU when compiling for DOS// + - //83 Selected -gen gas ASM backend for non-x86 CPU// + - //84 -asm att used for -gen gas, but -gen gas only supports -asm intel// + - //85 -pic used when making executable (only works when making a shared library)// + - //86 -pic used, but not supported by target system (only works for non-x86 Unixes)// + - //87 Var-len strings cannot be initialized// + - //88 Recursive TYPE or UNION not allowed// + - //89 Recursive DEFINE not allowed// + - //90 Identifier cannot include periods// + - //91 Executable not found// + - //92 Array out-of-bounds// + - //93 Missing command-line option for// + - //94 Expected 'ANY'// + - //95 Expected 'END SCOPE'// + - //96 Illegal inside a compound statement or scoped block// + - //97 UDT function results cannot be passed by reference// + - //98 Ambiguous call to overloaded function// + - //99 No matching overloaded function// + - //100 Division by zero// + - //101 Cannot pop stack, underflow// + - //102 UDT's containing var-len string fields cannot be initialized// + - //103 Branching to scope block containing local variables// + - //104 Branching to other functions or to module-level// + - //105 Branch crossing local array, var-len string or object definition// + - //106 LOOP without DO// + - //107 NEXT without FOR// + - //108 WEND without WHILE// + - //109 END WITH without WITH// + - //110 END IF without IF// + - //111 END SELECT without SELECT// + - //112 END SUB or FUNCTION without SUB or FUNCTION// + - //113 END SCOPE without SCOPE// + - //114 END NAMESPACE without NAMESPACE// + - //115 END EXTERN without EXTERN// + - //116 ELSEIF without IF// + - //117 ELSE without IF// + - //118 CASE without SELECT// + - //119 Cannot modify a constant// + - //120 Expected period ('.')// + - //121 Expected 'END NAMESPACE'// + - //122 Illegal inside a NAMESPACE block// + - //123 Symbols defined inside namespaces cannot be removed// + - //124 Expected 'END EXTERN'// + - //125 Expected 'END SUB'// + - //126 Expected 'END FUNCTION'// + - //127 Expected 'END CONSTRUCTOR'// + - //128 Expected 'END DESTRUCTOR'// + - //129 Expected 'END OPERATOR'// + - //130 Expected 'END PROPERTY'// + - //131 Declaration outside the original namespace// + - //132 No end of multi-line comment, expected "'/"// + - //133 Too many errors, exiting// + - //134 Expected 'ENDMACRO'// + - //135 EXTERN or COMMON variables cannot be initialized// + - //136 EXTERN or COMMON dynamic arrays cannot have initial bounds// + - //137 At least one parameter must be a user-defined type// + - //138 Parameter or result must be a user-defined type// + - //139 Both parameters can't be of the same type// + - //140 Parameter and result can't be of the same type// + - //141 Invalid result type for this operator// + - //142 Invalid parameter type, it must be the same as the parent TYPE/CLASS// + - //143 Vararg parameters are not allowed in overloaded functions// + - //144 Illegal outside an OPERATOR block// + - //145 Parameter cannot be optional// + - //146 Only valid in -lang// + - //147 Default types or suffixes are only valid in -lang// + - //148 Suffixes are only valid in -lang// + - //149 Implicit variables are only valid in -lang// + - //150 Auto variables are only valid in -lang// + - //151 Invalid array index// + - //152 Operator must be a member function// + - //153 Operator cannot be a member function// + - //154 Method declared in anonymous UDT// + - //155 Constant declared in anonymous UDT// + - //156 Static variable declared in anonymous UDT// + - //157 Expected operator// + - //158 Declaration outside the original namespace or class// + - //159 A destructor should not have any parameters// + - //160 Expected class or UDT identifier// + - //161 Var-len strings cannot be part of UNION's or nested TYPE's// + - //162 Dynamic arrays cannot be part of UNION's or nested TYPE's// + - //163 Fields with constructors cannot be part of UNION's or nested TYPE's// + - //164 Fields with destructors cannot be part of UNION's or nested TYPE's// + - //165 Illegal outside a CONSTRUCTOR block// + - //166 Illegal outside a DESTRUCTOR block// + - //167 UDT's with methods must have unique names// + - //168 Parent is not a class or UDT// + - //169 CONSTRUCTOR() chain call not at top of constructor// + - //170 BASE() initializer not at top of constructor// + - //171 REDIM on UDT with non-CDECL constructor// + - //172 REDIM on UDT with non-CDECL destructor// + - //173 REDIM on UDT with non-parameterless default constructor// + - //174 ERASE on UDT with non-CDECL constructor// + - //175 ERASE on UDT with non-CDECL destructor// + - //176 ERASE on UDT with non-parameterless default constructor// + - //177 This symbol cannot be undefined// + - //178 RETURN mixed with 'FUNCTION =' or EXIT FUNCTION (using both styles together is unsupported when returning objects with constructors)// + - //179 'FUNCTION =' or EXIT FUNCTION mixed with RETURN (using both styles together is unsupported when returning objects with constructors)// + - //180 Missing RETURN to copy-construct function result// + - //181 Invalid assignment/conversion// + - //182 Invalid array subscript// + - //183 TYPE or CLASS has no default constructor// + - //184 Function result TYPE has no default constructor// + - //185 Missing BASE() initializer (base UDT without default constructor requires manual initialization)// + - //186 Missing default constructor implementation (base UDT without default constructor requires manual initialization)// + - //187 Missing UDT.constructor(byref as UDT) implementation (base UDT without default constructor requires manual initialization)// + - //188 Missing UDT.constructor(byref as const UDT) implementation (base UDT without default constructor requires manual initialization)// + - //189 Invalid priority attribute// + - //190 PROPERTY GET should have no parameter, or just one if indexed// + - //191 PROPERTY SET should have one parameter, or just two if indexed// + - //192 Expected 'PROPERTY'// + - //193 Illegal outside a PROPERTY block// + - //194 PROPERTY has no GET method/accessor// + - //195 PROPERTY has no SET method/accessor// + - //196 PROPERTY has no indexed GET method/accessor// + - //197 PROPERTY has no indexed SET method/accessor// + - //198 Missing overloaded operator: // + - //199 The NEW[] operator does not allow explicit calls to constructors// + - //200 The NEW[] operator only supports the { ANY } initialization// + - //201 The NEW operator cannot be used with fixed-length strings// + - //202 Illegal member access// + - //203 Expected ':'// + - //204 The default constructor has no public access// + - //205 Constructor has no public access// + - //206 Destructor has no public access// + - //207 Accessing base UDT's private default constructor// + - //208 Accessing base UDT's private destructor// + - //209 Illegal non-static member access// + - //210 Constructor declared ABSTRACT// + - //211 Constructor declared VIRTUAL// + - //212 Destructor declared ABSTRACT// + - //213 Member cannot be static// + - //214 Member isn't static// + - //215 Only static members can be accessed from static functions// + - //216 The PRIVATE and PUBLIC attributes are not allowed with REDIM, COMMON or EXTERN// + - //217 STATIC used here, but not the in the DECLARE statement// + - //218 CONST used here, but not the in the DECLARE statement// + - //219 VIRTUAL used here, but not the in the DECLARE statement// + - //220 ABSTRACT used here, but not the in the DECLARE statement// + - //221 Method declared VIRTUAL, but UDT does not extend OBJECT// + - //222 Method declared ABSTRACT, but UDT does not extend OBJECT// + - //223 Not overriding any virtual method// + - //224 Implemented body for an ABSTRACT method// + - //225 Override has different return type than overridden method// + - //226 Override has different calling convention than overridden method// + - //227 Implicit destructor override would have different calling convention// + - //228 Implicit LET operator override would have different calling convention// + - //229 Override is not a CONST member like the overridden method// + - //230 Override is a CONST member, but the overridden method is not// + - //231 Override has different parameters than overridden method// + - //232 This operator cannot be STATIC// + - //233 This operator is implicitly STATIC and cannot be VIRTUAL or ABSTRACT// + - //234 This operator is implicitly STATIC and cannot be CONST// + - //235 Parameter must be an integer// + - //236 Parameter must be a pointer// + - //237 Expected initializer// + - //238 Fields cannot be named as keywords in TYPE's that contain member functions or in CLASS'es// + - //239 Illegal outside a FOR compound statement// + - //240 Illegal outside a DO compound statement// + - //241 Illegal outside a WHILE compound statement// + - //242 Illegal outside a SELECT compound statement// + - //243 Expected 'FOR'// + - //244 Expected 'DO'// + - //245 Expected 'WHILE'// + - //246 Expected 'SELECT'// + - //247 No outer FOR compound statement found// + - //248 No outer DO compound statement found// + - //249 No outer WHILE compound statement found// + - //250 No outer SELECT compound statement found// + - //251 Expected 'CONSTRUCTOR', 'DESTRUCTOR', 'DO', 'FOR', 'FUNCTION', 'OPERATOR', 'PROPERTY', 'SELECT', 'SUB' or 'WHILE'// + - //252 Expected 'DO', 'FOR' or 'WHILE'// + - //253 Illegal outside a SUB block// + - //254 Illegal outside a FUNCTION block// + - //255 Ambiguous symbol access, explicit scope resolution required// + - //256 An ENUM, TYPE or UNION cannot be empty// + - //257 ENUM's declared inside EXTERN .. END EXTERN blocks don't open new scopes// + - //258 STATIC used on non-member procedure// + - //259 CONST used on non-member procedure// + - //260 ABSTRACT used on non-member procedure// + - //261 VIRTUAL used on non-member procedure// + - //262 Invalid initializer// + - //263 Objects with default [con|de]structors or methods are only allowed in the module level// + - //264 Static member variable in nested UDT (only allowed in toplevel UDTs)// + - //265 Symbol not a CLASS, ENUM, TYPE or UNION type// + - //266 Too many elements// + - //267 Only data members supported// + - //268 UNIONs are not allowed// + - //269 Arrays are not allowed// + - //270 COMMON variables cannot be object instances of CLASS/TYPE's with cons/destructors// + - //271 Cloning operators (LET, Copy constructors) can't take a byval arg of the parent's type// + - //272 Local symbols can't be referenced// + - //273 Expected 'PTR' or 'POINTER'// + - //274 Too many levels of pointer indirection// + - //275 Dynamic arrays can't be const// + - //276 Const UDT cannot invoke non-const method// + - //277 Elements must be empty for strings and arrays// + - //278 GOSUB disabled, use 'OPTION GOSUB' to enable// + - //279 Invalid -lang// + - //280 Can't use ANY as initializer in array with ellipsis bound// + - //281 Must have initializer with array with ellipsis bound// + - //282 Can't use ... as lower bound// + - //283 FOR/NEXT variable name mismatch// + - //284 Selected option requires an SSE FPU mode// + - //285 Expected relational operator ( =, >, <, <>, <=, >= )// + - //286 Unsupported statement in -gen gcc mode// + - //287 Too many labels// + - //288 Unsupported function// + - //289 Expected sub// + - //290 Expected '#ENDIF'// + - //291 Resource file given for target system that does not support them// + - //292 -o option without corresponding input file// + - //293 Not extending a TYPE/UNION (a TYPE/UNION can only extend other TYPEs/UNIONs)// + - //294 Illegal outside a CLASS, TYPE or UNION method// + - //295 CLASS, TYPE or UNION not derived// + - //296 CLASS, TYPE or UNION has no constructor// + - //297 Symbol type has no Run-Time Type Info (RTTI)// + - //298 Types have no hierarchical relation// + - //299 Expected a CLASS, TYPE or UNION symbol type// + - //300 Casting derived UDT pointer from incompatible pointer type// + - //301 Casting derived UDT pointer from unrelated UDT pointer type// + - //302 Casting derived UDT pointer to incompatible pointer type// + - //303 Casting derived UDT pointer to unrelated UDT pointer type// + - //304 ALIAS name string is empty// + - //305 LIB name string is empty// + - //306 UDT has unimplemented abstract methods// + - //307 Non-virtual call to ABSTRACT method// + - //308 #ASSERT condition failed// + - //309 Expected '>'// + - //310 Invalid size// + - //311 ALIAS name here does not match ALIAS given in DECLARE prototype// + - //312 vararg parameters are only allowed in CDECL procedures// + - //313 the first parameter in a procedure may not be vararg// + - //314 CONST used on constructor (not needed)// + - //315 CONST used on destructor (not needed)// + - //316 Byref function result not set// + - //317 Function result assignment outside of the function// + - //318 Type mismatch in byref function result assignment// + - //319 -asm att|intel option given, but not supported for this target (only x86 or x86_64)// + - //320 Reference not initialized// + - //321 Incompatible reference initializer// + - //322 Array of references - not supported yet// + - //323 Invalid CASE range, start value is greater than the end value// + - //324 Fixed-length string combined with BYREF (not supported)// ==Third party programs errors== These errors occur after the source has been compiled into assembler, they come from the auxiliary programs FB requires to compile a source into an executable: the linker, the assembler and (for Windows programs) the resource compiler. diff --git a/doc/manual/cache/KeyPgFunctionPtr.wakka b/doc/manual/cache/KeyPgFunctionPtr.wakka index 592fc4cddc..627de5428f 100644 --- a/doc/manual/cache/KeyPgFunctionPtr.wakka +++ b/doc/manual/cache/KeyPgFunctionPtr.wakka @@ -16,7 +16,7 @@ Data type that stores a pointer to a ##[[KeyPgFunction|FUNCTION]]## procedure re {{fbdoc item="desc"}} A ##[[KeyPgFunction|Function]]## pointer is a procedure pointer that stores the memory location of compiled code that returns a value. If no intializer is given the default initial value is zero (0). - The memory address for the ##[[KeyPgFunction|Function]]## procedure can be assigned to the variable by taking the address of a subroutine with ##[[KeyPgOpProcPtr|ProcPtr]]## or ##[[KeyPgOpAt|Operator @ (Address of)]]##. + The memory address for the ##[[KeyPgFunction|Function]]## procedure can be assigned to the variable by taking the address of a subroutine with ##[[KeyPgOpProcptr|ProcPtr]]## or ##[[KeyPgOpAt|Operator @ (Address of)]]##. The procedure must match the same ##[[KeyPgFunction|Function]]## declaration as the declared ##[[KeyPgFunction|Function]]## pointer. @@ -97,7 +97,7 @@ Print operation(4, @x3) {{fbdoc item="see"}} - ##[[KeyPgSub|Sub]]## - - ##[[KeyPgOpProcPtr|ProcPtr]]## + - ##[[KeyPgOpProcptr|ProcPtr]]## - ##[[KeyPgOpAt|Operator @ (Address of)]]## {{fbdoc item="back" value="CatPgStdDataTypes|Standard Data Types"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgOpDeleteOverload.wakka b/doc/manual/cache/KeyPgOpDeleteOverload.wakka new file mode 100644 index 0000000000..aee2b3d995 --- /dev/null +++ b/doc/manual/cache/KeyPgOpDeleteOverload.wakka @@ -0,0 +1,36 @@ +{{fbdoc item="title" value="Operator Delete Overload"}}---- +Member operator to overload memory deallocation process part provided by ##[[KeyPgOpDelete|Operator Delete Statement]]## when applying to a UDT (User Defined Type). + +{{fbdoc item="syntax"}}## + [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **delete** ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) + [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **delete[]** ( //buf// [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] ) +## +{{fbdoc item="param"}} + ##//buf//## + A pointer to memory that has been allocated by ##[[KeyPgOpNewOverload|New Overload]]## operator or ##**New[] Overload**## operator, the array-version of ##[[KeyPgOpNewOverload|New Overload]]## operator. + +{{fbdoc item="desc"}} + The member operator ##**Delete Overload**## overloads the memory deallocation process part provided by the ##[[KeyPgOpDelete|Delete Statement]]## operator when applying to a UDT (User Defined Type). So the user can define its own memory deallocation process part. + But before that, the UDT instance destruction process part provided by the ##[[KeyPgOpDelete|Delete Statement]]## operator is not modified. + + ##**Delete[] Overload**## operator is the array-version of ##**Delete Overload**## operator and overloads the memory deallocation process provided by the ##**Delete[] Statement**## operator when applying to a UDT (User Defined Type). + + Memory freed with ##**Delete Overload**## operator must have be allocated with ##[[KeyPgOpNewOverload|New Overload]]## operator. Memory freed with ##**Delete[] Overload**## operator must have been allocated with ##**New[] Overload operator**##, the array-version of ##[[KeyPgOpNewOverload|New Overload]]## operator. You cannot mix and match the different versions of the operators. + + Member operators ##**Delete Overload**##, and ##**Delete[] Overload**## are always static, even if not explicitly declared (##[[KeyPgStaticMember|static]]## keyword is unnecessary but allowed). Thus, they do not have an implicit ##[[KeyPgThis|This]]## instance argument passed to them (because instance already been destroyed). + +{{fbdoc item="ex"}} + See the ##[[KeyPgOpNewOverload|New Overload]]## operator examples. + +{{fbdoc item="lang"}} + - Only available in the //[[CompilerOptlang|-lang fb]]// dialect. + +{{fbdoc item="diff"}} + - New to ""FreeBASIC"" + +{{fbdoc item="see"}} + - ##[[KeyPgOpDelete|Delete Statement]]## + - ##[[KeyPgOpNewOverload|New Overload]]## + - ##[[KeyPgDeallocate|Deallocate]]## + +{{fbdoc item="back" value="CatPgOpMemory|Memory Operators"}}{{fbdoc item="back" value="CatPgOperators|Operators"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgOpNewOverload.wakka b/doc/manual/cache/KeyPgOpNewOverload.wakka new file mode 100644 index 0000000000..1fe65e7337 --- /dev/null +++ b/doc/manual/cache/KeyPgOpNewOverload.wakka @@ -0,0 +1,302 @@ +{{fbdoc item="title" value="Operator New Overload"}}---- +Member operator to overload dynamic memory allocation process part provided by ##[[KeyPgOpNew|Operator New Expression]]## when applying to a UDT (User Defined Type). + +{{fbdoc item="syntax"}}## + [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **new** ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] + [[KeyPgDeclare|declare]] [[KeyPgOperator|operator]] **new[]** ( //size// [[KeyPgAs|as]] [[KeyPgUinteger|uinteger]] ) [[KeyPgAs|as]] [[KeyPgAny|any]] [[KeyPgPtr|ptr]] +## +{{fbdoc item="param"}} + ##//size//## + Number of bytes to allocate. + +{{fbdoc item="ret"}} + A pointer of type [[KeyPgAny|any]] [[KeyPgPtr|ptr]] to the start of the newly allocated memory. + +{{fbdoc item="desc"}} + The member operator ##**New Overload**## overloads the dynamic memory allocation process part provided by the ##[[KeyPgOpNew|New Expression]]## operator when applying to a UDT (User Defined Type). So the user can define its own dynamic memory allocation process part. + But after that, the UDT instance construction process part provided by the ##[[KeyPgOpNew|New Expression]]## operator is not modified. + + ##**New[] Overload**## operator is the array-version of the ##**New Overload**## operator and overloads the dynamic memory allocation process provided by the ##**New[] Expression**## operator when applying to a UDT (User Defined Type). + + Memory allocated with ##**New Overload**## operator must be freed with ##[[KeyPgOpDeleteOverload|Delete Overload]]## operator. Memory allocated with ##**New[] Overload**## operator must be freed with ##**Delete[] Overload**## operator, the array-version of ##[[KeyPgOpDeleteOverload|Delete Overload]]## operator. You cannot mix and match the different versions of the operators. + + Member operators ##**New Overload**##, and ##**New[] Overload**## are always static, even if not explicitly declared (##[[KeyPgStaticMember|static]]## keyword is unnecessary but allowed). Thus, they do not have an implicit ##[[KeyPgThis|This]]## instance argument passed to them (because instance not yet been constructed). + +{{fbdoc item="ex"}} + + Aligned memory allocator: + - by using the member operators "New Overload" and "Delete Overload", any created User object is aligned to a multiple of "ALIGN" bytes (256 bytes in this example), + - the real pointer of the allocated memory is saved just above the User pointer, in the padding block. +{{fbdoc item="filename" value="examples/manual/udt/newoverload1.bas"}} + %%(freebasic) +Const ALIGN = 256 + +Type UDT + Dim As Byte a(0 to 10 * 1024 * 1024 - 1) '' 10 megabyte fixed array + Declare Operator New (Byval size As UInteger) As Any Ptr + Declare Operator Delete (Byval buffer As Any Ptr) + Declare Constructor () + Declare Destructor () +End Type + +Operator UDT.New (Byval size As UInteger) As Any Ptr + Print " Overloaded New operator, with parameter size = &h" & Hex(size) + Dim pOrig As Any Ptr = Callocate(ALIGN-1 + Sizeof(UDT Ptr) + size) + Dim pMin As Any Ptr = pOrig + Sizeof(UDT Ptr) + Dim p As Any Ptr = pMin + ALIGN-1 - (Culng(pMin + ALIGN-1) Mod ALIGN) + Cast(Any Ptr Ptr, p)[-1] = pOrig + Operator = p + Print " real pointer = &h" & Hex(pOrig), "return pointer = &h" & Hex(p) +End Operator + +Operator UDT.Delete (Byval buffer As Any Ptr) + Print " Overloaded Delete operator, with parameter buffer = &h" & Hex(buffer) + Dim pOrig As Any Ptr = Cast(Any Ptr Ptr, buffer)[-1] + Deallocate(pOrig) + Print " real pointer = &h" & Hex(pOrig) +End Operator + +Constructor UDT () + Print " Constructor, @This = &h" & Hex(@This) +End Constructor + +Destructor UDT () + Print " Destructor, @This = &h" & Hex(@This) +End destructor + +Print "'Dim As UDT Ptr p = New UDT'" +Dim As UDT Ptr p = New UDT + +Print " p = &h" & Hex(p) + +Print "'Delete p'" +Delete p + +Sleep +%% + + Output example: + %% +'Dim As UDT Ptr p = New UDT' + Overloaded New operator, with parameter size = &hA00000 + real pointer = &h420020 return pointer = &h420100 + Constructor, @This = &h420100 + p = &h420100 +'Delete p' + Destructor, @This = &h420100 + Overloaded Delete operator, with parameter buffer = &h420100 + real pointer = &h420020 +%% + + Dynamic allocation manager for UDT, by using the member operators "New[] Overload" and "Delete[] Overload": + - monitoring of memory allocations/deallocations: addresses, sizes and total memory used, + - detection of abnormal deallocation requests, + - detection of a failed allocation (Allocate() returning null pointer), + - detection of total allocated memory size exceeding a threshold, + - the last two detection cases induces an automatic memory freeing before forcing the program to end. + The principle is to manage a dynamic list of successful allocations, but not yet freed, containing the allocated addresses with their requested sizes: +{{fbdoc item="filename" value="examples/manual/udt/newoverload2.bas"}} + %%(freebasic) +Type UDTmanager + '' user UDT fields: + Dim As Byte b(1 to 1024*1024) + '' manager fields: + Public: + Declare Operator New[] (Byval size As Uinteger) As Any Ptr + Declare Operator Delete[] (Byval buf As Any Ptr) + Static As Uinteger maxmemory + Private: + Static As Any Ptr address() + Static As Uinteger bytes() + Static upbound As Uinteger + Declare Static Function printLine (Byref text As String, Byval index As Uinteger, Byval sign As Integer) As Uinteger + Declare Static Sub endProgram () +End Type + +Dim As Uinteger UDTmanager.maxmemory = 3 * 1024 * 1024 * 1024 +Redim UDTmanager.address(0) +Redim UDTmanager.bytes(0) +Dim UDTmanager.upbound As Uinteger = 0 + +Function UDTmanager.printLine (Byref text As String, Byval index As Uinteger, Byval sign As Integer) As Uinteger + Dim As UInteger total = 0 + For I As Uinteger = 1 To UDTmanager.upbound + If I <> index Orelse Sgn(sign) > 0 Then + total += UDTmanager.bytes(I) + End If + Next I + Print text, "&h"; + Print Hex(UDTmanager.address(index), Sizeof(Any Ptr) * 2), + If sign <> 0 Then + Print Using " +####.## MB"; Sgn(sign) * Cast(Integer, UDTmanager.bytes(index) / 1024) / 1024; + Else + Print Using "( ####.## MB)"; UDTmanager.bytes(index) / 1024 / 1024; + End If + Print, + Print Using "###.## GB"; total / 1024 / 1024 / 1024 + Return total +End Function + +Sub UDTmanager.endProgram () + Do While UDTmanager.upbound > 0 + Deallocate UDTmanager.address(UDTmanager.upbound) + UDTmanager.printLine("memory deallocation forced", UDTmanager.upbound, -1) + UDTmanager.upbound -= 1 + Redim Preserve UDTmanager.address(UDTmanager.upbound) + Redim Preserve UDTmanager.bytes(UDTmanager.upbound) + Loop + Print "end program forced" + Print + Sleep + End +End Sub + +Operator UDTmanager.New[] (Byval size As Uinteger) As Any Ptr + Dim As Any Ptr p = Allocate(size) + If p > 0 Then + UDTmanager.upbound += 1 + Redim Preserve UDTmanager.address(UDTmanager.upbound) + Redim Preserve UDTmanager.bytes(UDTmanager.upbound) + UDTmanager.address(UDTmanager.upbound) = p + UDTmanager.bytes(UDTmanager.upbound) = size + If UDTmanager.printLine("memory allocation", UDTmanager.upbound, +1) > UDTmanager.maxmemory Then + UDTmanager.address(0) = p + UDTmanager.bytes(0) = size + Print + UDTmanager.printLine("memory allocation exceeded", 0, 0) + UDTmanager.endProgram() + End If + Return p + Else + UDTmanager.address(0) = p + UDTmanager.bytes(0) = size + Print + UDTmanager.printLine("memory allocation failed", 0, 0) + UDTmanager.endProgram() + End If +End Operator + +Operator UDTmanager.Delete[] (Byval buf As Any Ptr) + Dim As Uinteger found = 0 + For I As Uinteger = 1 To UDTmanager.upbound + If UDTmanager.address(I) = buf Then + Deallocate buf + UDTmanager.printLine("memory deallocation", I, -1) + For J As Uinteger = I + 1 To UDTmanager.upbound + UDTmanager.address(J - 1) = UDTmanager.address(J) + UDTmanager.bytes(J - 1) = UDTmanager.bytes(J) + Next J + UDTmanager.upbound -= 1 + Redim Preserve UDTmanager.address(UDTmanager.upbound) + Redim Preserve UDTmanager.bytes(UDTmanager.upbound) + found = 1 + Exit For + End If + Next I + If found = 0 Then + UDTmanager.address(0) = buf + UDTmanager.bytes(0) = 0 + UDTmanager.printLine("deallocation not matching", 0, 0) + End If +End Operator + + +Print "Message",, "Address"& Space(Sizeof(Any Ptr)), "Size", "Total" +Print +Randomize +Dim As UDTmanager Ptr pu1 = New UDTmanager[Rnd() * 256 + 1] +Dim As UDTmanager Ptr pu2 = New UDTmanager[Rnd() * 256 + 1] +Dim As UDTmanager Ptr pu3 = Cast(UDTmanager Ptr, 1) +Delete[] pu2 +Delete[] pu3 +Delete[] pu2 +Delete[] pu1 +Do + Dim As UDTmanager Ptr pu = New UDTmanager[Rnd() * 512 + 1] +Loop +%% + + Output for fbc 32-bit (maximum dynamic data < 2 GB). + Here, program is stopped because of memory allocation failed: + %% +Message Address Size Total + +memory allocation &h020E0020 +99.00 MB 0.10 GB +memory allocation &h083F3020 +3.00 MB 0.10 GB +memory deallocation &h083F3020 -3.00 MB 0.10 GB +deallocation not matching &h00000001 ( 0.00 MB) 0.10 GB +deallocation not matching &h083F3020 ( 0.00 MB) 0.10 GB +memory deallocation &h020E0020 -99.00 MB 0.00 GB +memory allocation &h020ED020 +103.00 MB 0.10 GB +memory allocation &h087F2020 +106.00 MB 0.20 GB +memory allocation &h0F20D020 +230.00 MB 0.43 GB +memory allocation &h1D812020 +137.00 MB 0.56 GB +memory allocation &h2612C020 +377.00 MB 0.93 GB +memory allocation &h3DA30020 +275.00 MB 1.20 GB +memory allocation &h4ED40020 +220.00 MB 1.41 GB +memory allocation &h5C958020 +229.00 MB 1.64 GB + +memory allocation failed &h00000000 ( 142.00 MB) 1.64 GB +memory deallocation forced &h5C958020 -229.00 MB 1.41 GB +memory deallocation forced &h4ED40020 -220.00 MB 1.20 GB +memory deallocation forced &h3DA30020 -275.00 MB 0.93 GB +memory deallocation forced &h2612C020 -377.00 MB 0.56 GB +memory deallocation forced &h1D812020 -137.00 MB 0.43 GB +memory deallocation forced &h0F20D020 -230.00 MB 0.20 GB +memory deallocation forced &h087F2020 -106.00 MB 0.10 GB +memory deallocation forced &h020ED020 -103.00 MB 0.00 GB +end program forced +%% + Output for fbc 64-bit (maximum dynamic data < virtual memory). + Here, program is stopped because of total allocated memory size > 3 GB (adjustable threshold): + %% +Message Address Size Total + +memory allocation &h0000000001EA5040 +105.00 MB 0.10 GB +memory allocation &h00000000087BC040 +93.00 MB 0.19 GB +memory deallocation &h00000000087BC040 -93.00 MB 0.10 GB +deallocation not matching &h0000000000000001 ( 0.00 MB) 0.10 GB +deallocation not matching &h00000000087BC040 ( 0.00 MB) 0.10 GB +memory deallocation &h0000000001EA5040 -105.00 MB 0.00 GB +memory allocation &h0000000001EA1040 +155.00 MB 0.15 GB +memory allocation &h000000000B9BF040 +165.00 MB 0.31 GB +memory allocation &h0000000015ED8040 +382.00 MB 0.69 GB +memory allocation &h000000002DCE7040 +458.00 MB 1.13 GB +memory allocation &h000000004A6FB040 +255.00 MB 1.38 GB +memory allocation &h000000005A607040 +96.00 MB 1.48 GB +memory allocation &h000000006061B040 +426.00 MB 1.89 GB +memory allocation &h000000007FFF9040 +221.00 MB 2.11 GB +memory allocation &h000000008DD03040 +119.00 MB 2.22 GB +memory allocation &h0000000095413040 +147.00 MB 2.37 GB +memory allocation &h000000009E727040 +217.00 MB 2.58 GB +memory allocation &h00000000AC03C040 +334.00 MB 2.91 GB +memory allocation &h00000000C0E4B040 +280.00 MB 3.18 GB + +memory allocation exceeded &h00000000C0E4B040 ( 280.00 MB) 3.18 GB +memory deallocation forced &h00000000C0E4B040 -280.00 MB 2.91 GB +memory deallocation forced &h00000000AC03C040 -334.00 MB 2.58 GB +memory deallocation forced &h000000009E727040 -217.00 MB 2.37 GB +memory deallocation forced &h0000000095413040 -147.00 MB 2.22 GB +memory deallocation forced &h000000008DD03040 -119.00 MB 2.11 GB +memory deallocation forced &h000000007FFF9040 -221.00 MB 1.89 GB +memory deallocation forced &h000000006061B040 -426.00 MB 1.48 GB +memory deallocation forced &h000000005A607040 -96.00 MB 1.38 GB +memory deallocation forced &h000000004A6FB040 -255.00 MB 1.13 GB +memory deallocation forced &h000000002DCE7040 -458.00 MB 0.69 GB +memory deallocation forced &h0000000015ED8040 -382.00 MB 0.31 GB +memory deallocation forced &h000000000B9BF040 -165.00 MB 0.15 GB +memory deallocation forced &h0000000001EA1040 -155.00 MB 0.00 GB +end program forced +%% +{{fbdoc item="lang"}} + - Only available in the //[[CompilerOptlang|-lang fb]]// dialect. + +{{fbdoc item="diff"}} + - New to ""FreeBASIC"" + +{{fbdoc item="see"}} + - ##[[KeyPgOpNew|New Expression]]## + - ##[[KeyPgOpDeleteOverload|Delete Overload]]## + - ##[[KeyPgAllocate|Allocate]]## + +{{fbdoc item="back" value="CatPgOpMemory|Memory Operators"}}{{fbdoc item="back" value="CatPgOperators|Operators"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgSubPtr.wakka b/doc/manual/cache/KeyPgSubPtr.wakka index e3fd928096..6663035ea8 100644 --- a/doc/manual/cache/KeyPgSubPtr.wakka +++ b/doc/manual/cache/KeyPgSubPtr.wakka @@ -15,7 +15,7 @@ Data type that stores a pointer to a ##[[KeyPgSub|SUB]]## procedure {{fbdoc item="desc"}} A ##[[KeyPgSub|Sub]]## pointer is a procedure pointer that stores the memory location of compiled code. If no intializer is given the default initial value is zero (0). - The memory address for the ##[[KeyPgSub|Sub]]## procedure can be assigned to the variable by taking the address of a subroutine with ##[[KeyPgOpProcPtr|ProcPtr]]## or ##[[KeyPgOpAt|Operator @ (Address of)]]##. + The memory address for the ##[[KeyPgSub|Sub]]## procedure can be assigned to the variable by taking the address of a subroutine with ##[[KeyPgOpProcptr|ProcPtr]]## or ##[[KeyPgOpAt|Operator @ (Address of)]]##. The procedure must match the same ##[[KeyPgSub|Sub]]## declaration as the declared ##[[KeyPgSub|Sub]]## pointer. @@ -117,7 +117,7 @@ s2_ptr("PI", 3.14) {{fbdoc item="see"}} - ##[[KeyPgSub|Sub]]## - - ##[[KeyPgOpProcPtr|ProcPtr]]## + - ##[[KeyPgOpProcptr|ProcPtr]]## - ##[[KeyPgOpAt|Operator @ (Address of)]]## {{fbdoc item="back" value="CatPgStdDataTypes|Standard Data Types"}} diff --git a/doc/manual/cache/PrintToc.wakka b/doc/manual/cache/PrintToc.wakka index 444608b74c..3026045f7c 100644 --- a/doc/manual/cache/PrintToc.wakka +++ b/doc/manual/cache/PrintToc.wakka @@ -270,6 +270,7 @@ [[KeyPgFreefile|FREEFILE]] [[KeyPgFunction|FUNCTION]] [[KeyPgMemberFunction|FUNCTION (Member)]] + [[KeyPgFunctionPtr|FUNCTION (Pointer)]] {{fbdoc item="subsect" value="G"}} [[KeyPgGetgraphics|GET (Graphics)]] @@ -513,6 +514,7 @@ [[KeyPgOpStrptr|STRPTR]] [[KeyPgSub|SUB]] [[KeyPgMemberSub|SUB (Member)]] + [[KeyPgSubPtr|SUB (Pointer)]] [[KeyPgSwap|SWAP]] [[KeyPgSystem|SYSTEM]] @@ -693,10 +695,10 @@ {{fbdoc item="subsect" value="Memory operators"}} [[KeyPgOpNew|Operator New Expression]] - [[KeyPgOpNewOverload|Operator New Overload]] + [[KeyPgOpNewOverload|Operator New Overload]] [[KeyPgOpPlacementNew|Operator Placement New]] [[KeyPgOpDelete|Operator Delete Statement]] - [[KeyPgOpDeleteOverload|Operator Delete Overload]] + [[KeyPgOpDeleteOverload|Operator Delete Overload]] {{fbdoc item="subsect" value="Iterating operators"}} [[KeyPgOpFor|Operator For]] @@ -975,6 +977,7 @@ [[CompilerOptmt|-mt]] [[CompilerOptnodeflibs|-nodeflibs]] [[CompilerOptnoerrline|-noerrline]] + [[CompilerOptnoobjinfo|-noobjinfo]] [[CompilerOpto|-o < name >]] [[CompilerOptoptimization|-O < level >]] [[CompilerOptp|-p < name >]] @@ -990,8 +993,8 @@ [[CompilerOpts|-s < name >]] [[CompilerOptshowincludes|-showincludes]] [[CompilerOptstatic|-static]] - [[CompilerOpttarget|-target < platform >]] [[CompilerOptt|-t < value >]] + [[CompilerOpttarget|-target < platform >]] [[CompilerOptv|-v]] [[CompilerOptvec|-vec < level >]] [[CompilerOptversion|-version]] @@ -1004,6 +1007,7 @@ [[DebuggerRunning|Debugging with FreeBASIC]] [[CompilerErrMsg|Compiler Error Messages]] [[CompilerTools|Tools used by fbc]] + [[CompilerInstallingGcc|Installing gcc for -gen gcc]] {{fbdoc item="section" value="FreeBASIC dialects and QBASIC"}} [[CompilerQB|FreeBASIC and Qbasic]] From 5b8451d4c209a782eabec4527df4de7df01c5303 Mon Sep 17 00:00:00 2001 From: coderJeff Date: Mon, 3 Sep 2018 17:15:56 -0400 Subject: [PATCH 5/7] fbdoc: examples/manual update 2018-09-03 --- examples/manual/array/redim.bas | 1 - examples/manual/array/redim3.bas | 22 +++ examples/manual/datatype/funcptr.bas | 15 ++ examples/manual/datatype/funcptr2.bas | 22 +++ examples/manual/datatype/funcptr3.bas | 47 ++++++ examples/manual/datatype/subptr.bas | 23 +++ examples/manual/datatype/subptr2.bas | 27 ++++ examples/manual/datatype/subptr3.bas | 55 +++++++ examples/manual/fileio/basicvsc.bas | 140 +++++++++--------- examples/manual/fileio/get.bas | 20 +-- examples/manual/gfx/pcopy_cons.bas | 4 + examples/manual/input/inkeyext.bas | 4 + examples/manual/libraries/aspell.bas | 2 +- examples/manual/libraries/cairo.bas | 2 +- examples/manual/libraries/cryptlib.bas | 4 +- examples/manual/libraries/expat.bas | 13 +- examples/manual/libraries/libxml.bas | 4 +- examples/manual/procs/byref-result2.bas | 12 +- examples/manual/procs/vararg2.bas | 76 ++++++++++ .../proguide/arrays/fixedlen_bounds.bas | 2 +- examples/manual/proguide/object-class.bas | 134 ++++++++++++++--- examples/manual/system/dir.bas | 2 +- examples/manual/udt/newoverload1.bas | 52 +++++++ examples/manual/udt/newoverload2.bas | 124 ++++++++++++++++ examples/manual/udt/virtual1.bas | 49 +++--- examples/manual/udt/virtual2.bas | 58 ++++++++ 26 files changed, 769 insertions(+), 145 deletions(-) create mode 100644 examples/manual/array/redim3.bas create mode 100644 examples/manual/datatype/funcptr.bas create mode 100644 examples/manual/datatype/funcptr2.bas create mode 100644 examples/manual/datatype/funcptr3.bas create mode 100644 examples/manual/datatype/subptr.bas create mode 100644 examples/manual/datatype/subptr2.bas create mode 100644 examples/manual/datatype/subptr3.bas create mode 100644 examples/manual/procs/vararg2.bas create mode 100644 examples/manual/udt/newoverload1.bas create mode 100644 examples/manual/udt/newoverload2.bas create mode 100644 examples/manual/udt/virtual2.bas diff --git a/examples/manual/array/redim.bas b/examples/manual/array/redim.bas index cf7322ab36..01431ead23 100644 --- a/examples/manual/array/redim.bas +++ b/examples/manual/array/redim.bas @@ -7,7 +7,6 @@ '' -------- '' Define a variable-length array with 5 elements -'' ReDim array(0 To 4) As Integer For index As Integer = LBound(array) To UBound(array) diff --git a/examples/manual/array/redim3.bas b/examples/manual/array/redim3.bas new file mode 100644 index 0000000000..cee76c0540 --- /dev/null +++ b/examples/manual/array/redim3.bas @@ -0,0 +1,22 @@ +'' examples/manual/array/redim3.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgRedim +'' -------- + +'' Define a variable-length array as UDT field +Type UDT + Dim As Integer array(Any) +End Type + +Dim As UDT u(0 To 3) + +'' For use of Redim with a complex array expression +'' (especially if the array expression itself contains parentheses), +'' the array expression must be enclosed in parentheses +'' in order to solve the parsing ambiguity: +'' Redim u(0).array(0 To 9) +'' induces error 4: Duplicated definition, u in 'Redim u(0).array(0 To 9)' +ReDim (u(0).array)(0 To 9) diff --git a/examples/manual/datatype/funcptr.bas b/examples/manual/datatype/funcptr.bas new file mode 100644 index 0000000000..8ce9f3e4b4 --- /dev/null +++ b/examples/manual/datatype/funcptr.bas @@ -0,0 +1,15 @@ +'' examples/manual/datatype/funcptr.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgFunctionPtr +'' -------- + +Function ConcatSelf( x As String ) As String + Return x & x +End Function + +Dim x As Function( x As String ) As String = ProcPtr( ConcatSelf ) + +Print x( "Hello" ) diff --git a/examples/manual/datatype/funcptr2.bas b/examples/manual/datatype/funcptr2.bas new file mode 100644 index 0000000000..7a2853810e --- /dev/null +++ b/examples/manual/datatype/funcptr2.bas @@ -0,0 +1,22 @@ +'' examples/manual/datatype/funcptr2.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgFunctionPtr +'' -------- + +Function x2 (ByVal i As Integer) As Integer + Return i * 2 +End Function + +Function x3 (ByVal i As Integer) As Integer + Return i * 3 +End Function + +Function operation (ByVal i As Integer, ByVal op As Function (ByVal As Integer) As Integer) As Integer + Return op(i) +End Function + +Print operation(4, @x2) +Print operation(4, @x3) diff --git a/examples/manual/datatype/funcptr3.bas b/examples/manual/datatype/funcptr3.bas new file mode 100644 index 0000000000..873f79c27f --- /dev/null +++ b/examples/manual/datatype/funcptr3.bas @@ -0,0 +1,47 @@ +'' examples/manual/datatype/funcptr3.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgFunctionPtr +'' -------- + +' Example of basic callback Function mechanism to implement a key pressed event: +' (the user callback Function address cannot be modified while the event thread is running) +' - An asynchronous thread tests the keyboard in a loop, and calls a user callback Function each time a key is pressed. +' - The callback Function address is passed to the thread. +' - The callback Function prints the character of the key pressed, +' but if the key pressed is it orders the thread to finish by using the function return value. +' - As the user callback address is passed to the thread as argument, it cannot be modified while the thread is running. + + +'' thread Sub definition + Sub threadInkey (ByVal p As Any Ptr) + If p > 0 Then '' test condition callback Function defined + Dim As Function (ByRef As String) As Integer callback = p '' convert the any ptr to a callback Function pointer + Do + Dim As String s = Inkey + If s <> "" Then '' test condition key pressed + If callback(s) Then '' test condition to finish thread + Exit Do + End If + End If + Sleep 50 + Loop + End If + End Sub + +'' user callback Function definition + Function printInkey (ByRef s As String) As Integer + If Asc(s) = 27 Then '' test condition key pressed = + Print + Return -1 '' order thread to finish + Else + Print s; + Return 0 '' order thread to continue + End If + End Function + +'' user main code + Dim As Any Ptr p = ThreadCreate(@threadInkey, @printInkey) '' launch the thread, passing the callback Function address + ThreadWait(p) '' wait for the thread finish diff --git a/examples/manual/datatype/subptr.bas b/examples/manual/datatype/subptr.bas new file mode 100644 index 0000000000..74f8c7e78b --- /dev/null +++ b/examples/manual/datatype/subptr.bas @@ -0,0 +1,23 @@ +'' examples/manual/datatype/subptr.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgSubPtr +'' -------- + + Sub Hello() + Print "Hello" + End Sub + + Sub Goodbye() + Print "Goodbye" + End Sub + + Dim x As Sub() = ProcPtr( Hello ) + + x() + + x = @Goodbye '' or procptr(Goodbye) + + x() diff --git a/examples/manual/datatype/subptr2.bas b/examples/manual/datatype/subptr2.bas new file mode 100644 index 0000000000..86e3701e73 --- /dev/null +++ b/examples/manual/datatype/subptr2.bas @@ -0,0 +1,27 @@ +'' examples/manual/datatype/subptr2.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgSubPtr +'' -------- + +Sub s0 () + Print "'s0 ()'" +End Sub + +Sub s1 (ByVal I As Integer) + Print "'s1 (Byval As Integer)'", I +End Sub + +Sub s2 (ByRef S As String, ByVal D As Double) + Print "'s2 (Byref As String, Byval As Double)'", S, D +End Sub + +Dim s0_ptr As Sub () = @s0 +Dim s1_ptr As Sub (ByVal I As Integer) = @s1 +Dim s2_ptr As Sub (ByRef S As String, ByVal D As Double) = @s2 + +s0_ptr() +s1_ptr(3) +s2_ptr("PI", 3.14) diff --git a/examples/manual/datatype/subptr3.bas b/examples/manual/datatype/subptr3.bas new file mode 100644 index 0000000000..1b140bcf5c --- /dev/null +++ b/examples/manual/datatype/subptr3.bas @@ -0,0 +1,55 @@ +'' examples/manual/datatype/subptr3.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgSubPtr +'' -------- + +' Example of advanced callback Sub mechanism to implement a key pressed event: +' (the user callback Sub address can be modified while the event thread is running) +' - An asynchronous thread tests the keyboard in a loop, and calls a user callback Sub each time a key is pressed. +' - An UDT groups the common variables used (callback Sub pointer, character of key pressed, thread end flag), +' and the static thread Sub plus the thread handle. +' - An UDT instance pointer is passed to the thread, which then transmits it to the callback Sub each time. +' - The callback Sub prints the character of the key pressed character, +' but if the key pressed is it orders the thread to finish. +' - As the user callback pointer is a member field of the UDT, it can be modified while the thread is running. + + +'' UDT for thread environment + Type threadUDT + Dim As Sub (ByVal As ThreadUDT Ptr) callback '' callback Sub pointer + Dim As Integer threadEnd '' thread end flag + Dim As String s '' character of the key pressed + Declare Static Sub threadInkey (ByVal p As Any Ptr) '' static thread Sub + Dim As Any Ptr threadHandle '' handle to the thread + End Type + +'' thread Sub definition + Sub threadUDT.threadInkey (ByVal p As Any Ptr) + Dim As threadUDT Ptr pt = p '' convert the any ptr to a threadUDT pointer + Do + pt->s = Inkey + If pt->s <> "" AndAlso pt->callback > 0 Then '' test condition key pressed & callback Sub defined + pt->callback(p) + End If + Sleep 50 + Loop Until pt->threadEnd '' test condition to finish thread + End Sub + +'' user callback Sub definition + Sub printInkey (ByVal pt As threadUDT Ptr) + If Asc(pt->s) = 27 Then '' test condition key pressed = + pt->threadEnd = -1 '' order thread to finish + Print + Else + Print pt->s; + End If + End Sub + +'' user main code + Dim As ThreadUDT t '' create an instance of threadUDT + t.threadHandle = ThreadCreate(@threadUDT.threadInkey, @t) '' launch the thread, passing the instance address + t.callback = @printInkey '' initialize the callback Sub pointer + ThreadWait(t.threadHandle) '' wait for the thread finish diff --git a/examples/manual/fileio/basicvsc.bas b/examples/manual/fileio/basicvsc.bas index 132bdbf52d..2e5c1de767 100644 --- a/examples/manual/fileio/basicvsc.bas +++ b/examples/manual/fileio/basicvsc.bas @@ -6,87 +6,81 @@ '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgFileIO '' -------- -Data " File I/O example & test GET vs FREAD | (CL) 2008-10-12 Public Domain " -Data " http://www.freebasic.net/wiki/wikka.php?wakka=ProPgFileIO " -Rem -Rem Compile With FB 0.20 Or newer -Rem -Rem In the commandline supply preferably 2 different files of same big size -Rem Default Is "BLAH" For both (bad) -Rem In both loops (Get And FREAD) the last Read can be "empty" ... no problem +'==== File I/O example / 2018-05-18 ==== -#include "crt\stdio.bi" '' Otherwise the "C"-stuff won't work +Dim As String fileName = "test_123.tmp" +Dim As ULong buffer(0 To 99) '100 x 4 bytes +Dim As Integer numItems, result -Dim As FILE Ptr QQ '' This is the C-like file access pointer -Dim As UByte Ptr BUF '' Buffer used for both FB-like and C-like read -Dim As UInteger FILN '' FB-like "filenumber" +Print !"\n==== Using the C Runtime (CRT) file I/O ====\n" -Dim As UInteger AA, BB, CC, DD, EE -Dim As ULongInt II64 '' We do try to support files >= 4 GiB +#include Once "crt/stdio.bi" -Dim As String VGSTEMP, VGSFILE1, VGSFILE2 +Dim As FILE Ptr filePtr -? : Read VGSTEMP : ? VGSTEMP : Read VGSTEMP : ? VGSTEMP : ? +'open in binary writing mode +filePtr = fopen(fileName, "wb") +If filePtr <> 0 Then + 'write 75 x 4 = 300 bytes + numItems = fwrite(@buffer(0), SizeOf(buffer(0)), 75, filePtr) + Print "Number of bytes written: " & Str(numItems * SizeOf(buffer(0))) + Print "Number of items written: " & Str(numItems) + fclose(filePtr) +Else + Print "Failed to open " & fileName & " for writing" +End If -VGSTEMP=Command$(1) : VGSFILE1="BLAH" -If (VGSTEMP<>"") Then VGSFILE1=VGSTEMP -VGSTEMP=Command$(2) : VGSFILE2=VGSFILE1 -If (VGSTEMP<>"") Then VGSFILE2=VGSTEMP +'open in binary reading mode +filePtr = fopen(fileName, "rb") +If filePtr <> 0 Then + 'skip the first 25 items + If fseek(filePtr, SizeOf(buffer(0)) * 25, SEEK_SET) <> 0 Then + Print "Failed to seek (set file stream position)" + End If + 'try to read the next 100 items + numItems = fread(@buffer(0), SizeOf(buffer(0)), 100, filePtr) + Print "Number of bytes read: " & Str(numItems * SizeOf(buffer(0))) + Print "Number of items read: " & Str(numItems) + fclose(filePtr) +Else + Print "Failed to open " & fileName & " for reading" +End If -BUF = Allocate(32768) '' 32 KiB - hoping it won't fail, BUF could be 0 ... +result = remove(fileName) 'delete file +If result = 0 Then Print "Removed: " & fileName -? : ? "FB - OPEN - GET , """+VGSFILE1+"""": Sleep 1000 -FILN = FreeFile : AA=0 : II64=0 '' AA counts blocks per 32 KiB already read -BB=Open (VGSFILE1 For Binary Access Read As #FILN) -'' Result 0 is OK here, <>0 is evil -'' "ACCESS READ" should prevent file creation if it doesn't exist -? "OPEN result : " ; BB -If (BB=0) Then '' BB will be "reused" for timer below - BB=Cast(UInteger,(Timer*100)) '' No UINTEGER TIMER in FB, make units 10 ms - CC=Get (#FILN,,*BUF,32768,DD) - '' CC has the success status, 0 is OK, <>0 is bad - '' DD is the amount of data read - '' EOF is __NOT__ considered as error here - ? "0th GET : ";CC;" ";DD - ? "2 bytes read : ";BUF[0];" ";BUF[1] - Do - AA=AA+1 : II64=II64+Cast(ULongInt,DD) - If (DD<32768) Or (CC<>0) Then Exit Do '' Give up - CC=Get (#FILN,,*BUF,32768,DD) - Loop - EE=Cast(UInteger,(Timer*100))-BB - ? "Time : ";(EE+1)*10;" ms" - If (AA>1) Then ? "Last GET : ";CC;" ";DD - ? "Got __EXACTLY__ ";II64;" bytes in ";AA;" calls" - Close #FILN -ENDIF +Print !"\n==== Using the FreeBASIC file I/O ====\n" -? : ? "C - FOPEN - FREAD , """+VGSFILE2+"""" : Sleep 1000 -AA=0 : II64=0 '' AA counts blocks per 32 KiB already read -QQ=FOPEN(VGSFILE2,"rb") -'' Here 0 is evil and <>0 good, opposite from above !!! -'' File will not be created if it doesn't exist (good) -'' "rb" is case sensitive and must be lowercase, STRPTR seems not necessary -? "FOPEN result : " ; QQ -If (QQ<>0) Then - BB=Cast(UInteger,(Timer*100)) '' No UINTEGER TIMER in FB, make units 10 ms - DD=FREAD(BUF,1,32768,QQ) '' 1 is size of byte - can't live without :-D - '' Returns size of data read, <32768 on EOF, 0 after EOF, or "-1" on error - ? "0th FREAD : ";DD - ? "2 bytes read : ";BUF[0];" ";BUF[1] - Do - AA=AA+1 - If (DD<=32768) Then II64=II64+Cast(ULongInt,DD) - If (DD<>32768) Then Exit Do '' ERR or EOF - DD=FREAD(BUF,1,32768,QQ) - Loop - EE=Cast(UInteger,(Timer*100))-BB - ? "Time : ";(EE+1)*10;" ms" - If (AA>1) Then ? "Last FREAD : ";DD - ? "Got __EXACTLY__ ";II64;" bytes in ";AA;" calls" - FCLOSE(QQ) -ENDIF +Dim As Long fileNum +Dim As Integer numBytes -Deallocate(BUF): Sleep 1000 '' Crucial +fileNum = FreeFile +'open in binary writing mode +If Open(fileName, For Binary, Access Write, As fileNum) = 0 Then + 'write 75 x 4 = 300 bytes + result = Put(fileNum, , buffer(0), 75) 'No @buffer(0) + numBytes = Seek(fileNum) - 1 'FreeBASIC file position is 1-based + Print "Number of bytes written: " & Str(numBytes) + Print "Number of items written: " & Str(numBytes \ SizeOf(buffer(0))) + Close(fileNum) +Else + Print "Failed to open " & fileName & " for writing" +End If -End +'open in binary reading mode +If Open(fileName, For Binary, Access Read, As fileNum) = 0 Then + 'skip the first 25 items + Seek fileNum, 25 * SizeOf(buffer(0)) + 1 'Note: +1 & seek(...) not allowed + 'try to read the next 100 items + result = Get(fileNum, , buffer(0), 100, numBytes) + Print "Number of bytes read: " & Str(numBytes) + Print "Number of items read: " & Str(numBytes \ SizeOf(buffer(0))) + Close(fileNum) +Else + Print "Failed to open " & fileName & " for reading" +End If + +result = Kill(fileName) 'delete file +If result = 0 Then Print "Killed: " & fileName + +Print !"\n==== End ====\n" diff --git a/examples/manual/fileio/get.bas b/examples/manual/fileio/get.bas index b070b3a8be..1b27e77da2 100644 --- a/examples/manual/fileio/get.bas +++ b/examples/manual/fileio/get.bas @@ -8,11 +8,11 @@ Dim Shared f As Integer -Sub get_integer() +Sub get_long() - Dim buffer As Integer ' Integer variable + Dim buffer As Long ' Long variable - ' Read an Integer (4 bytes) from the file into buffer, using file number "f". + ' Read a Long (4 bytes) from the file into buffer, using file number "f". Get #f, , buffer ' print out result @@ -23,9 +23,9 @@ End Sub Sub get_array() - Dim an_array(0 To 10-1) As Integer ' array of Integers + Dim an_array(0 To 10-1) As Long ' array of Longs - ' Read 10 Integers (10 * 4 = 40 bytes) from the file into an_array, using file number "f". + ' Read 10 Longs (10 * 4 = 40 bytes) from the file into an_array, using file number "f". Get #f, , an_array() ' print out result @@ -38,12 +38,12 @@ End Sub Sub get_mem - Dim pmem As Integer Ptr + Dim pmem As Long Ptr - ' allocate memory for 5 Integers - pmem = Allocate(5 * SizeOf(Integer)) + ' allocate memory for 5 Longs + pmem = Allocate(5 * SizeOf(Long)) - ' Read 5 integers (5 * 4 = 20 bytes) from the file into allocated memory + ' Read 5 Longs (5 * 4 = 20 bytes) from the file into allocated memory Get #f, , *pmem, 5 ' Note pmem must be dereferenced (*pmem, or pmem[0]) ' print out result using [] Pointer Indexing @@ -63,7 +63,7 @@ f = FreeFile ' Open the file "file.ext" for binary usage, using the file number "f". Open "file.ext" For Binary As #f - get_integer() + get_long() get_array() diff --git a/examples/manual/gfx/pcopy_cons.bas b/examples/manual/gfx/pcopy_cons.bas index e6babbb999..da1efa6985 100644 --- a/examples/manual/gfx/pcopy_cons.bas +++ b/examples/manual/gfx/pcopy_cons.bas @@ -6,6 +6,10 @@ '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgPcopy '' -------- +'' Compile with -lang fblite or qb + +#lang "fblite" + '' Console mode example: '' Set the working page number to 0, and the visible page number to 1 diff --git a/examples/manual/input/inkeyext.bas b/examples/manual/input/inkeyext.bas index e07d05f9dd..71a31e5615 100644 --- a/examples/manual/input/inkeyext.bas +++ b/examples/manual/input/inkeyext.bas @@ -6,6 +6,10 @@ '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgInkey '' -------- +'' Compile with -lang fblite or qb + +#lang "fblite" + #if __FB_LANG__ = "qb" #define EXTCHAR Chr$(0) #else diff --git a/examples/manual/libraries/aspell.bas b/examples/manual/libraries/aspell.bas index 89a1f7e68a..05f7e7f6c9 100644 --- a/examples/manual/libraries/aspell.bas +++ b/examples/manual/libraries/aspell.bas @@ -38,7 +38,7 @@ Do Dim As AspellStringEnumeration Ptr elements = _ aspell_word_list_elements(aspell_speller_suggest(speller, StrPtr(word), Len(word))) Do - Dim As ZString Ptr w = aspell_string_enumeration_next(elements) + Dim As const ZString Ptr w = aspell_string_enumeration_next(elements) If (w = 0) Then Exit Do End If diff --git a/examples/manual/libraries/cairo.bas b/examples/manual/libraries/cairo.bas index 173c1854bd..1a3c0f4895 100644 --- a/examples/manual/libraries/cairo.bas +++ b/examples/manual/libraries/cairo.bas @@ -15,7 +15,7 @@ Const SCREEN_H = 300 ScreenRes SCREEN_W, SCREEN_H, 32 '' Create a cairo drawing context, using the FB screen as surface. -Var surface = cairo_image_surface_create_for_data(ScreenPtr(), CAIRO_FORMAT_ARGB32, SCREEN_W, SCREEN_H, SCREEN_W * SizeOf(Integer)) +Var surface = cairo_image_surface_create_for_data(ScreenPtr(), CAIRO_FORMAT_ARGB32, SCREEN_W, SCREEN_H, SCREEN_W * SizeOf(ULong)) Var c = cairo_create(surface) diff --git a/examples/manual/libraries/cryptlib.bas b/examples/manual/libraries/cryptlib.bas index 64ece17352..0be324cfdc 100644 --- a/examples/manual/libraries/cryptlib.bas +++ b/examples/manual/libraries/cryptlib.bas @@ -63,8 +63,8 @@ End Function cryptInit( ) '' calculate hashes - Print "md5: "; calc_hash( filename, CRYPT_ALGO_MD5 ) - Print "sha: "; calc_hash( filename, CRYPT_ALGO_SHA ) + Print "md5: "; calc_hash( filename, CRYPT_ALGO_MD5 ) + Print "sha1: "; calc_hash( filename, CRYPT_ALGO_SHA1 ) '' shutdown cryptlib cryptEnd( ) diff --git a/examples/manual/libraries/expat.bas b/examples/manual/libraries/expat.bas index 335eb084e6..1cbf8b0fc0 100644 --- a/examples/manual/libraries/expat.bas +++ b/examples/manual/libraries/expat.bas @@ -12,8 +12,11 @@ '#define XML_UNICODE #include Once "expat.bi" +#include Once "crt/mem.bi" +#ifndef False #define False 0 +#endif #define NULL 0 Const BUFFER_SIZE = 1024 @@ -30,8 +33,8 @@ Dim Shared As Context ctx Sub elementBegin cdecl _ ( _ ByVal userdata As Any Ptr, _ - ByVal element As XML_char Ptr, _ - ByVal attributes As XML_char Ptr Ptr _ + ByVal element As const XML_char Ptr, _ + ByVal attributes As const XML_char Ptr Ptr _ ) '' Show its name @@ -55,7 +58,7 @@ Sub elementBegin cdecl _ End Sub '' Callback called by libexpat when end of XML tag is found -Sub elementEnd cdecl(ByVal userdata As Any Ptr, ByVal element As XML_char Ptr) +Sub elementEnd cdecl(ByVal userdata As Any Ptr, ByVal element As const XML_char Ptr) '' Show text collected in charData() callback below Print Space(ctx.nesting);ctx.text ctx.text[0] = 0 @@ -66,7 +69,7 @@ End Sub Sub charData cdecl _ ( _ ByVal userdata As Any Ptr, _ - ByVal chars As XML_char Ptr, _ '' Note: not null-terminated + ByVal chars As const XML_char Ptr, _ '' Note: not null-terminated ByVal length As Integer _ ) @@ -75,7 +78,7 @@ Sub charData cdecl _ '' Append to our buffer, if there still is free room, so we can print it out later If (length <= (BUFFER_SIZE - ctx.textlength)) Then - fb_MemCopy(ctx.text[ctx.textlength], chars[0], length * SizeOf(XML_char)) + memcpy(@ctx.text[ctx.textlength], @chars[0], length * SizeOf(XML_char)) ctx.textlength += length ctx.text[ctx.textlength] = 0 End If diff --git a/examples/manual/libraries/libxml.bas b/examples/manual/libraries/libxml.bas index e408f5f5f5..2d7067ca99 100644 --- a/examples/manual/libraries/libxml.bas +++ b/examples/manual/libraries/libxml.bas @@ -23,8 +23,8 @@ End If Dim As Integer ret = xmlTextReaderRead( reader ) Do While( ret = 1 ) - Dim As ZString Ptr constname = xmlTextReaderConstName( reader ) - Dim As ZString Ptr value = xmlTextReaderConstValue( reader ) + Dim As const ZString Ptr constname = xmlTextReaderConstName( reader ) + Dim As const ZString Ptr value = xmlTextReaderConstValue( reader ) Print xmlTextReaderDepth( reader ); _ xmlTextReaderNodeType( reader ); _ diff --git a/examples/manual/procs/byref-result2.bas b/examples/manual/procs/byref-result2.bas index 4395eb3fad..4b976e5279 100644 --- a/examples/manual/procs/byref-result2.bas +++ b/examples/manual/procs/byref-result2.bas @@ -14,16 +14,20 @@ Function f1( ) ByRef As String End Function Function f2( ByRef _s As String ) ByRef As String - '' This variable-length string will be returned by reference, no copy will be created. + '' This variable-length string will transit by reference (input and output), no copy will be created. Function = _s End Function s = "abcd" Print s -f1( ) &= "efgh" +f1( ) = f1( ) & "efgh" +Print s + +'' The enclosing parentheses are required here on the left-hand side. +( f2( s ) ) = f2( s ) & "ijkl" Print s -'' At time of writing, the enclosing parentheses are required here. -( f2( s ) ) &= "ijkl" +'' The enclosing parentheses are not required here on the left-hand side. +f2( s ) => f2( s ) & "mnop" Print s diff --git a/examples/manual/procs/vararg2.bas b/examples/manual/procs/vararg2.bas new file mode 100644 index 0000000000..89b9d911e3 --- /dev/null +++ b/examples/manual/procs/vararg2.bas @@ -0,0 +1,76 @@ +'' examples/manual/procs/vararg2.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgVaFirst +'' -------- + +'' Example of a simple custom printf +Sub myprintf cdecl(ByRef formatstring As String, ...) + '' Get the pointer to the first var-arg + Dim As Any Ptr arg = va_first() + + '' For each char in format string... + Dim As UByte Ptr p = StrPtr(formatstring) + Dim As Integer todo = Len(formatstring) + While (todo > 0) + Dim As Integer char = *p + p += 1 + todo -= 1 + + '' Is it a format char? + If (char = Asc("%")) Then + If (todo = 0) Then + '' % at the end + Print "%"; + Exit While + End If + + '' The next char should tell the type + char = *p + p += 1 + todo -= 1 + + '' Print var-arg, depending on the type + Select Case char + '' integer? + Case Asc("i") + Print Str(va_arg(arg, Integer)); + '' Note, different from C: va_next() must be + '' used as va_arg() won't update the pointer. + arg = va_next(arg, Integer) + + '' long integer? (64-bit) + Case Asc("l") + Print Str(va_arg(arg, LongInt)); + arg = va_next(arg, LongInt) + + '' single or double? + '' Note: because the C ABI, all singles passed on + '' var-args are converted to doubles. + Case Asc( "f" ), Asc( "d" ) + Print Str(va_arg(arg, Double)); + arg = va_next(arg, Double) + + '' string? + Case Asc("s") + '' Strings are passed byval, so the length is unknown + Print *va_arg(arg, ZString Ptr); + arg = va_next(arg, ZString Ptr) + + End Select + + '' Ordinary char, just print as-is + Else + Print Chr( char ); + End If + Wend +End Sub + + Dim As String s = "bar" + + myprintf(!"integer=%i, longint=%l single=%f, double=%d, string=%s, string=%s\n", _ + 1, 1ll Shl 32, 2.2, 3.3, "foo", s) + + Sleep diff --git a/examples/manual/proguide/arrays/fixedlen_bounds.bas b/examples/manual/proguide/arrays/fixedlen_bounds.bas index 47d2b905c7..b3986aa0bf 100644 --- a/examples/manual/proguide/arrays/fixedlen_bounds.bas +++ b/examples/manual/proguide/arrays/fixedlen_bounds.bas @@ -11,4 +11,4 @@ Dim b(0 To 1) As Integer '' 1-dimensional, 2 elements (0 and 1) Dim c(5 To 10) As Integer '' 1-dimensional, 5 elements (5, 6, 7, 8, 9 and 10) Dim d(1 To 2, 1 To 2) As Integer '' 2-dimensional, 4 elements: (1,1), (1,2), (2,1), (2,2) -Dim e(255, 255, 255, 255) As Integer '' 4-dimensional, 256 * 256 * 256 * 256 elements +Dim e(99, 99, 99, 99) As Integer '' 4-dimensional, 100 * 100 * 100 * 100 elements diff --git a/examples/manual/proguide/object-class.bas b/examples/manual/proguide/object-class.bas index d472e4eb37..0c2963cbe9 100644 --- a/examples/manual/proguide/object-class.bas +++ b/examples/manual/proguide/object-class.bas @@ -9,10 +9,10 @@ '' Sample Type showing available methods and operators '' Practically this is a pointless example, as the only '' data member is an Integer. It serves only as a -'' demonstration and guide. +'' guide to syntax. '' '' There are many other combinations that can be -'' used in pass parameters. For simplicity +'' used in passed parameters. For simplicity '' This example only uses byref and type T '' where ever possible. @@ -71,6 +71,13 @@ Type T '' Nonstatic Member Declarations: + '' Memory Allocation/Deallocation + + Declare Operator New ( ByVal size As UInteger ) As Any Ptr + Declare Operator New[] ( ByVal size As UInteger ) As Any Ptr + Declare Operator Delete ( ByVal buf As Any Ptr ) + Declare Operator Delete[] ( ByVal buf As Any Ptr ) + '' Assignment Declare Operator Let ( ByRef rhs As T ) @@ -85,7 +92,6 @@ Type T Declare Operator += ( ByRef rhs As T ) Declare Operator += ( ByRef rhs As DataType ) - Declare Operator -= ( ByRef rhs As DataType ) Declare Operator *= ( ByRef rhs As DataType ) Declare Operator /= ( ByRef rhs As DataType ) @@ -99,30 +105,31 @@ Type T Declare Operator Imp= ( ByRef rhs As DataType ) Declare Operator Eqv= ( ByRef rhs As DataType ) Declare Operator ^= ( ByRef rhs As DataType ) - + Declare Operator &= ( ByRef rhs As DataType ) + '' Address of Declare Operator @ () As DataType Ptr '' Constructors can be overloaded - Declare Constructor() - Declare Constructor( ByRef rhs As T ) - Declare Constructor( ByRef rhs As DataType ) + Declare Constructor () + Declare Constructor ( ByRef rhs As T ) + Declare Constructor ( ByRef rhs As DataType ) '' There can be only one destructor - Declare Destructor() + Declare Destructor () '' Nonstatic member functions and subs '' overloaded procs must have different parameters - Declare Function f( ) As DataType - Declare Function f( ByRef arg1 As DataType ) As DataType + Declare Function f ( ) As DataType + Declare Function f ( ByRef arg1 As DataType ) As DataType - Declare Sub s( ) - Declare Sub s( ByRef arg1 As T ) - Declare Sub s( ByRef arg1 As DataType ) + Declare Sub s ( ) + Declare Sub s ( ByRef arg1 As T ) + Declare Sub s ( ByRef arg1 As DataType ) '' Properties @@ -132,6 +139,16 @@ Type T Declare Property pidx ( ByVal index As DataType ) As DataType Declare Property pidx ( ByVal index As DataType, ByRef new_value As DataType ) + '' Iterator + + Declare Operator For () + Declare Operator Step () + Declare Operator Next ( ByRef cond As T ) As Integer + + Declare Operator For ( ByRef stp As T ) + Declare Operator Step ( ByRef stp As T ) + Declare Operator Next ( ByRef cond As T, ByRef stp As T ) As Integer + End Type '' These must be global procedures @@ -167,6 +184,13 @@ Declare Operator < ( ByRef lhs As T, ByRef rhs As DataType ) As DataType Declare Operator > ( ByRef lhs As T, ByRef rhs As DataType ) As DataType Declare Operator <= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType Declare Operator >= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType +Declare Operator & ( ByRef lhs As T, ByRef rhs As DataType ) As DataType + +Declare Operator Abs ( ByRef arg As UDT ) As Double +Declare Operator Fix ( ByRef arg As UDT ) As Double +Declare Operator Frac ( ByRef arg As UDT ) As Double +Declare Operator Int ( ByRef arg As UDT ) As Double +Declare Operator Sgn ( ByRef arg As UDT ) As Double '' Global procedures (subs and funcs) can also accept the TYPE '' as a parameter or return it as a value, as could be done @@ -181,6 +205,22 @@ Declare Operator >= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType '' Name resolution in a NAMESPACE is same as other '' subs/funcs. Use USING or prefix the namespace name +Operator T.new ( ByVal size As UInteger ) As Any Ptr + Operator = Allocate( size ) +End Operator + +Operator T.new[] ( ByVal size As UInteger ) As Any Ptr + Operator = Allocate( size ) +End Operator + +Operator T.delete ( ByVal buf As Any Ptr ) + Deallocate buf +End Operator + +Operator T.delete[] ( ByVal buf As Any Ptr ) + Deallocate buf +End Operator + Operator T.let ( ByRef rhs As T ) value = rhs.value End Operator @@ -257,6 +297,11 @@ Operator T.^= ( ByRef rhs As DataType ) value ^= rhs End Operator +Operator T.&= ( ByRef rhs As DataType ) + Dim tmp As String + tmp &= Str( rhs ) +End Operator + Operator T.@ () As DataType Ptr Return( Cast( DataType Ptr, @This )) End Operator @@ -264,21 +309,24 @@ End Operator '' Constructors: -Constructor T() +Constructor T () + '' default constructor value = 0 End Constructor -Constructor T( ByRef rhs As T ) +Constructor T ( ByRef rhs As T ) + '' copy constructor value = rhs.value End Constructor -Constructor T( ByRef rhs As DataType ) +Constructor T ( ByRef rhs As DataType ) + '' custom constructor value = rhs End Constructor '' There can be only one destructor -Destructor T() +Destructor T () '' clean-up, none in this example End Destructor @@ -382,20 +430,43 @@ Operator >= ( ByRef lhs As T, ByRef rhs As DataType ) As DataType Return (lhs.value >= rhs) End Operator +Operator & ( ByRef lhs As T, ByRef rhs As DataType ) As DataType + Return Val(lhs.value & rhs) +End Operator + +Operator Abs ( ByRef arg As UDT ) As Double + Return Abs(arg.value) +End Operator + +Operator Fix ( ByRef arg As UDT ) As Double + Return Fix(arg.value) +End Operator + +Operator Frac ( ByRef arg As UDT ) As Double + Return Frac(arg.value) +End Operator + +Operator Int ( ByRef arg As UDT ) As Double + Return Int(arg.value) +End Operator + +Operator Sgn ( ByRef arg As UDT ) As Double + Return Sgn(arg.value) +End Operator '' Nonstatic member methods -Function T.f( ) As DataType +Function T.f ( ) As DataType Dim x As DataType Return x End Function -Function T.f( ByRef arg1 As DataType ) As DataType +Function T.f ( ByRef arg1 As DataType ) As DataType arg1 = this.value Return value End Function -Sub T.s( ) +Sub T.s ( ) '' refer to the type using '' with block @@ -411,11 +482,11 @@ Sub T.s( ) End Sub -Sub T.s( ByRef arg1 As T ) +Sub T.s ( ByRef arg1 As T ) value = arg1.value End Sub -Sub T.s( ByRef arg1 As DataType ) +Sub T.s ( ByRef arg1 As DataType ) value = arg1 End Sub @@ -439,6 +510,25 @@ Property T.pidx ( ByVal index As DataType, ByRef new_value As DataType ) value_array( index ) = new_value End Property +Operator T.for () +End Operator + +Operator T.step () +End Operator + +Operator T.next ( ByRef cond As T ) As Integer + Return 0 +End Operator + +Operator T.for ( ByRef stp As T ) +End Operator + +Operator T.step ( ByRef stp As T ) +End Operator + +Operator T.next ( ByRef cond As T, ByRef stp As T ) As Integer + Return 0 +End Operator '' new, delete, delete[] diff --git a/examples/manual/system/dir.bas b/examples/manual/system/dir.bas index 5381dc6596..1bab7cd2e0 100644 --- a/examples/manual/system/dir.bas +++ b/examples/manual/system/dir.bas @@ -12,7 +12,7 @@ Sub list_files (ByRef filespec As String, ByVal attrib As Integer) Dim As String filename = Dir(filespec, attrib) ' Start a file search with the specified filespec/attrib *AND* get the first filename. Do While Len(filename) > 0 ' If len(filename) is 0, exit the loop: no more filenames are left to be read. Print filename - filename = Dir() + filename = Dir() ' Search for (and get) the next item matching the initially specified filespec/attrib. Loop End Sub diff --git a/examples/manual/udt/newoverload1.bas b/examples/manual/udt/newoverload1.bas new file mode 100644 index 0000000000..fae619f947 --- /dev/null +++ b/examples/manual/udt/newoverload1.bas @@ -0,0 +1,52 @@ +'' examples/manual/udt/newoverload1.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgOpNewOverload +'' -------- + +Const ALIGN = 256 + +Type UDT + Dim As Byte a(0 To 10 * 1024 * 1024 - 1) '' 10 megabyte fixed array + Declare Operator New (ByVal size As UInteger) As Any Ptr + Declare Operator Delete (ByVal buffer As Any Ptr) + Declare Constructor () + Declare Destructor () +End Type + +Operator UDT.New (ByVal size As UInteger) As Any Ptr + Print " Overloaded New operator, with parameter size = &h" & Hex(size) + Dim pOrig As Any Ptr = CAllocate(ALIGN-1 + SizeOf(UDT Ptr) + size) + Dim pMin As Any Ptr = pOrig + SizeOf(UDT Ptr) + Dim p As Any Ptr = pMin + ALIGN-1 - (CULng(pMin + ALIGN-1) Mod ALIGN) + Cast(Any Ptr Ptr, p)[-1] = pOrig + Operator = p + Print " real pointer = &h" & Hex(pOrig), "return pointer = &h" & Hex(p) +End Operator + +Operator UDT.Delete (ByVal buffer As Any Ptr) + Print " Overloaded Delete operator, with parameter buffer = &h" & Hex(buffer) + Dim pOrig As Any Ptr = Cast(Any Ptr Ptr, buffer)[-1] + Deallocate(pOrig) + Print " real pointer = &h" & Hex(pOrig) +End Operator + +Constructor UDT () + Print " Constructor, @This = &h" & Hex(@This) +End Constructor + +Destructor UDT () + Print " Destructor, @This = &h" & Hex(@This) +End Destructor + +Print "'Dim As UDT Ptr p = New UDT'" +Dim As UDT Ptr p = New UDT + +Print " p = &h" & Hex(p) + +Print "'Delete p'" +Delete p + +Sleep diff --git a/examples/manual/udt/newoverload2.bas b/examples/manual/udt/newoverload2.bas new file mode 100644 index 0000000000..ff1d46271c --- /dev/null +++ b/examples/manual/udt/newoverload2.bas @@ -0,0 +1,124 @@ +'' examples/manual/udt/newoverload2.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgOpNewOverload +'' -------- + +Type UDTmanager + '' user UDT fields: + Dim As Byte b(1 To 1024*1024) + '' manager fields: + Public: + Declare Operator New[] (ByVal size As UInteger) As Any Ptr + Declare Operator Delete[] (ByVal buf As Any Ptr) + Static As UInteger maxmemory + Private: + Static As Any Ptr address() + Static As UInteger bytes() + Static upbound As UInteger + Declare Static Function printLine (ByRef text As String, ByVal index As UInteger, ByVal sign As Integer) As UInteger + Declare Static Sub endProgram () +End Type + +Dim As UInteger UDTmanager.maxmemory = 3 * 1024 * 1024 * 1024 +ReDim UDTmanager.address(0) +ReDim UDTmanager.bytes(0) +Dim UDTmanager.upbound As UInteger = 0 + +Function UDTmanager.printLine (ByRef text As String, ByVal index As UInteger, ByVal sign As Integer) As UInteger + Dim As UInteger total = 0 + For I As UInteger = 1 To UDTmanager.upbound + If I <> index OrElse Sgn(sign) > 0 Then + total += UDTmanager.bytes(I) + End If + Next I + Print text, "&h" & Hex(UDTmanager.address(index), SizeOf(Any Ptr) * 2), + If sign <> 0 Then + Print Using " +####.## MB"; Sgn(sign) * Cast(Integer, UDTmanager.bytes(index) / 1024) / 1024; + Else + Print Using "( ####.## MB)"; UDTmanager.bytes(index) / 1024 / 1024; + End If + Print, + Print Using "###.## GB"; total / 1024 / 1024 / 1024 + Return total +End Function + +Sub UDTmanager.endProgram () + Do While UDTmanager.upbound > 0 + Deallocate UDTmanager.address(UDTmanager.upbound) + UDTmanager.printLine("memory deallocation forced", UDTmanager.upbound, -1) + UDTmanager.upbound -= 1 + ReDim Preserve UDTmanager.address(UDTmanager.upbound) + ReDim Preserve UDTmanager.bytes(UDTmanager.upbound) + Loop + Print "end program forced" + Print + Sleep + End +End Sub + +Operator UDTmanager.New[] (ByVal size As UInteger) As Any Ptr + Dim As Any Ptr p = Allocate(size) + If p > 0 Then + UDTmanager.upbound += 1 + ReDim Preserve UDTmanager.address(UDTmanager.upbound) + ReDim Preserve UDTmanager.bytes(UDTmanager.upbound) + UDTmanager.address(UDTmanager.upbound) = p + UDTmanager.bytes(UDTmanager.upbound) = size + If UDTmanager.printLine("memory allocation", UDTmanager.upbound, +1) > UDTmanager.maxmemory Then + UDTmanager.address(0) = p + UDTmanager.bytes(0) = size + Print + UDTmanager.printLine("memory allocation exceeded", 0, 0) + UDTmanager.endProgram() + End If + Return p + Else + UDTmanager.address(0) = p + UDTmanager.bytes(0) = size + Print + UDTmanager.printLine("memory allocation failed", 0, 0) + UDTmanager.endProgram() + End If +End Operator + +Operator UDTmanager.Delete[] (ByVal buf As Any Ptr) + Dim As UInteger found = 0 + For I As UInteger = 1 To UDTmanager.upbound + If UDTmanager.address(I) = buf Then + Deallocate buf + UDTmanager.printLine("memory deallocation", I, -1) + For J As UInteger = I + 1 To UDTmanager.upbound + UDTmanager.address(J - 1) = UDTmanager.address(J) + UDTmanager.bytes(J - 1) = UDTmanager.bytes(J) + Next J + UDTmanager.upbound -= 1 + ReDim Preserve UDTmanager.address(UDTmanager.upbound) + ReDim Preserve UDTmanager.bytes(UDTmanager.upbound) + found = 1 + Exit For + End If + Next I + If found = 0 Then + UDTmanager.address(0) = buf + UDTmanager.bytes(0) = 0 + UDTmanager.printLine("deallocation not matching", 0, 0) + End If +End Operator + + +Print "Message",, "Address" & Space(SizeOf(Any Ptr)), "Size", "Total" +Print +Randomize +Dim As UDTmanager Ptr pu1 = New UDTmanager[Rnd() * 256 + 1] +Dim As UDTmanager Ptr pu2 = New UDTmanager[Rnd() * 256 + 1] +Dim As UDTmanager Ptr pu3 = Cast(UDTmanager Ptr, 1) +Delete[] pu2 +Delete[] pu3 +Delete[] pu2 +Delete[] pu1 +Do + Dim As UDTmanager Ptr pu = New UDTmanager[Rnd() * 512 + 1] +Loop diff --git a/examples/manual/udt/virtual1.bas b/examples/manual/udt/virtual1.bas index f6f773ff3b..7a55df027c 100644 --- a/examples/manual/udt/virtual1.bas +++ b/examples/manual/udt/virtual1.bas @@ -6,20 +6,23 @@ '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgVirtual '' -------- +'' Example with overriding subroutines + + Type Hello Extends Object Declare Virtual Sub hi( ) End Type Type HelloEnglish Extends Hello - Declare Sub hi( ) + Declare Sub hi( ) '' overriding subroutine End Type Type HelloFrench Extends Hello - Declare Sub hi( ) + Declare Sub hi( ) '' overriding subroutine End Type Type HelloGerman Extends Hello - Declare Sub hi( ) + Declare Sub hi( ) '' overriding subroutine End Type @@ -27,35 +30,37 @@ Sub Hello.hi( ) Print "hi!" End Sub -Sub HelloEnglish.hi( ) +Sub HelloEnglish.hi( ) '' overriding subroutine Print "hello!" End Sub -Sub HelloFrench.hi( ) +Sub HelloFrench.hi( ) '' overriding subroutine Print "Salut!" End Sub -Sub HelloGerman.hi( ) +Sub HelloGerman.hi( ) '' overriding subroutine Print "Hallo!" End Sub - Randomize( Timer( ) ) +Randomize( Timer( ) ) + +Dim As Hello Ptr h - Dim As Hello Ptr h +For i As Integer = 0 To 9 + Select Case( Int( Rnd( ) * 4 ) + 1 ) + Case 1 + h = New HelloEnglish + Case 2 + h = New HelloFrench + Case 3 + h = New HelloGerman + Case Else + h = New Hello + End Select - For i As Integer = 0 To 9 - Select Case( Int( Rnd( ) * 4 ) + 1 ) - Case 1 - h = New HelloEnglish - Case 2 - h = New HelloFrench - Case 3 - h = New HelloGerman - Case Else - h = New Hello - End Select + h->hi( ) + Delete h +Next - h->hi( ) - Delete h - Next +Sleep diff --git a/examples/manual/udt/virtual2.bas b/examples/manual/udt/virtual2.bas new file mode 100644 index 0000000000..bbf7feda86 --- /dev/null +++ b/examples/manual/udt/virtual2.bas @@ -0,0 +1,58 @@ +'' examples/manual/udt/virtual2.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgVirtual +'' -------- + +'' Example with overriding destructor and +'' overriding function with covariant return + + +Type myBase Extends Object + Declare Virtual Function clone () As myBase Ptr + Declare Virtual Sub Destroy () +End Type + +Function myBase.clone () As myBase Ptr + Dim As myBase Ptr pp = New myBase(This) + Print "myBase.clone() As myBase Ptr", pp + Function = pp +End Function + +Sub myBase.Destroy () + Print "myBase.Destroy()", , @This + Delete @This +End Sub + + +Type myDerived Extends myBase + Declare Function clone () As myDerived Ptr '' overriding member function with covariant return + Declare Sub Destroy () '' overriding member subroutine +End Type + +Function myDerived.clone () As myDerived Ptr '' overriding member function with covariant return + Dim As myDerived Ptr pc = New myDerived(This) + Print "myDerived.clone() As myDerived Ptr", pc + Function = pc +End Function + +Sub myDerived.Destroy () '' overriding member subroutine + Print "myDerived.Destroy()", , @This + Delete @This +End Sub + + +Dim As myDerived c + +Dim As myBase Ptr ppc = @c +Dim As myDerived Ptr pcc = @c + +Dim As myBase Ptr ppc1 = ppc->clone() '' using base pointers and polymorphism +Dim As myDerived Ptr pcc1 = pcc->clone() '' using derived pointers and covariance of return value +Print +ppc1->Destroy() '' using base pointer and polymorphism +pcc1->Destroy() '' using derived pointer + +Sleep From 13b4de39a29d0d370aaff6583c349f859d866ef7 Mon Sep 17 00:00:00 2001 From: coderJeff Date: Mon, 3 Sep 2018 20:11:59 -0400 Subject: [PATCH 6/7] fbdoc: udpate tools - doc/fbchkdoc/mkerrlst.bas fills in the text for Ambiguous LEN or SIZE of messsage - examples/manual/samples.bas accepts option to pass on addition compiler options to fbc - small fix in compiler/error.bas message - small fix to enable '-forcelang ' compiler option --- doc/fbchkdoc/mkerrlst.bas | 8 +++++++- examples/manual/samples.bas | 15 ++++++++++++--- src/compiler/error.bas | 2 +- src/compiler/fbc.bas | 2 +- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/doc/fbchkdoc/mkerrlst.bas b/doc/fbchkdoc/mkerrlst.bas index 823c6eb631..590bf48fe9 100644 --- a/doc/fbchkdoc/mkerrlst.bas +++ b/doc/fbchkdoc/mkerrlst.bas @@ -31,8 +31,14 @@ end sub '' sub WriteFooterCode( byval h as integer ) print #h, !"print" + print #h, !"dim msg as string" print #h, !"for i as integer = 1 to FB_WARNINGMSGS-1" - print #h, !"print chr(9) + \"- //\" + ltrim(str(i)) + \" \" + *warningMsgs(i).text + \"//\"" + print #h, !"if i = FB_WARNINGMSG_AMBIGIOUSLENSIZEOF then" + print #h, !"msg = ""Ambiguous LEN or SIZEOF""" + print #h, !"else" + print #h, !"msg = *warningMsgs(i).text" + print #h, !"end if" + print #h, !"print chr(9) + \"- //\" + ltrim(str(i)) + \" \" + msg + \"//\"" print #h, !"next" print #h, !"print: print: print" print #h, !"for i as integer = 1 to FB_ERRMSGS-1" diff --git a/examples/manual/samples.bas b/examples/manual/samples.bas index bf4618f984..6935675dc9 100644 --- a/examples/manual/samples.bas +++ b/examples/manual/samples.bas @@ -390,7 +390,8 @@ function DoCompile _ byref sourcedir as string, _ byref fbc as string, _ byref source as string, _ - byref target as string _ + byref target as string, _ + byref opts as string _ ) as integer dim i as integer @@ -409,7 +410,7 @@ function DoCompile _ args = sourcedir & source - args += " -x " & sourcedir & target + args += " " & opts & " -x " & sourcedir & target print fbc & " " & args ret = exec( fbc, args ) @@ -662,6 +663,7 @@ dim opt_specialonly as integer dim dirs() as string, ndirs as integer dim files() as string, nfiles as integer dim haderror as integer +dim extra_opts as string = "" ndirs = 0 nfiles = 0 @@ -711,6 +713,9 @@ case else print " -error" print " Abort on first error detected" print + print " -opts options" + print " Add options to the command line" + print end end select @@ -735,6 +740,10 @@ while( command(i) > "" ) case "-error" opt_error = TRUE + + case "-opts" + i += 1 + extra_opts = command(i) case else print "Unrecognized option '" & command(i) & "'" @@ -813,7 +822,7 @@ case CMD_COMPILE, CMD_CLEAN target = left(files(i), len(files(i))-4) & exe_ext if( cmd = CMD_COMPILE ) then - if( DoCompile( sourcedir, fbc, files(i), target ) = BUILD_FAIL ) then + if( DoCompile( sourcedir, fbc, files(i), target, extra_opts ) = BUILD_FAIL ) then haderror = TRUE if( opt_error ) then exit for diff --git a/src/compiler/error.bas b/src/compiler/error.bas index cbd42391c8..6a0ea50e6f 100644 --- a/src/compiler/error.bas +++ b/src/compiler/error.bas @@ -52,7 +52,7 @@ declare function hMakeParamDesc _ ( 1, @"Identifier's name too big, truncated" ), _ ( 1, @"Literal number too big, truncated" ), _ ( 1, @"Literal string too big, truncated" ), _ - ( 0, @"UDT with pointer or var-len string fields" ), _ + ( 0, @"UDT with pointer, var-len string, or var-len array fields" ), _ ( 0, @"Implicit variable allocation" ), _ ( 0, @"Missing closing quote in literal string" ), _ ( 0, @"Function result was not explicitly set" ), _ diff --git a/src/compiler/fbc.bas b/src/compiler/fbc.bas index 43dc12a7a3..5fe5717aec 100644 --- a/src/compiler/fbc.bas +++ b/src/compiler/fbc.bas @@ -1462,7 +1462,7 @@ dim shared as integer option_takes_argument(0 to (OPT__COUNT - 1)) = _ FALSE, _ '' OPT_EX FALSE, _ '' OPT_EXX FALSE, _ '' OPT_EXPORT - FALSE, _ '' OPT_FORCELANG + TRUE, _ '' OPT_FORCELANG TRUE , _ '' OPT_FPMODE TRUE , _ '' OPT_FPU FALSE, _ '' OPT_G From e4194cec79058273f0e9ea700506bad3cd9e725d Mon Sep 17 00:00:00 2001 From: coderJeff Date: Mon, 3 Sep 2018 20:12:49 -0400 Subject: [PATCH 7/7] fbdoc: wiki snapshot 2018-09-03 & update examples from examples/manual --- doc/manual/cache/CompilerErrMsg.wakka | 4 +- doc/manual/cache/CompilerOptw.wakka | 22 ++-- doc/manual/cache/ExtLibaspell.wakka | 64 +++++----- doc/manual/cache/ExtLibcryptlib.wakka | 60 ++++----- doc/manual/cache/ExtLibexpat.wakka | 125 ++++++++++--------- doc/manual/cache/ExtLiblibxml.wakka | 40 +++--- doc/manual/cache/KeyPgInkey.wakka | 4 + doc/manual/cache/KeyPgOpCombineModulus.wakka | 2 +- doc/manual/cache/KeyPgOpNewOverload.wakka | 53 ++++---- doc/manual/cache/KeyPgPcopy.wakka | 4 + doc/manual/cache/KeyPgPragma.wakka | 2 + doc/manual/cache/ProPgFixLenArrays.wakka | 10 +- 12 files changed, 204 insertions(+), 186 deletions(-) diff --git a/doc/manual/cache/CompilerErrMsg.wakka b/doc/manual/cache/CompilerErrMsg.wakka index 452c49d250..d48a4ae309 100644 --- a/doc/manual/cache/CompilerErrMsg.wakka +++ b/doc/manual/cache/CompilerErrMsg.wakka @@ -14,7 +14,7 @@ During the program compilation three types of errors can arise: - //7 Identifier's name too big, truncated// - //8 Literal number too big, truncated// - //9 Literal string too big, truncated// - - //10 UDT with pointer or var-len string fields// + - //10 UDT with pointer, var-len string, or var-len array fields// - //11 Implicit variable allocation// - //12 Missing closing quote in literal string// - //13 Function result was not explicitly set// @@ -41,7 +41,7 @@ During the program compilation three types of errors can arise: - //34 '=' parsed as equality operator in function argument, not assignment to BYREF function result// - //35 Mixing signed/unsigned operands// - //36 Mismatching parameter initializer// - - //37 // + - //37 Ambiguous LEN or SIZEOF// - //38 Suspicious logic operation, mixed boolean and non-boolean operands// - //39 Redefinition of intrinsic// - //40 CONST qualifier discarded// diff --git a/doc/manual/cache/CompilerOptw.wakka b/doc/manual/cache/CompilerOptw.wakka index 944501b2fb..74c92c01d6 100644 --- a/doc/manual/cache/CompilerOptw.wakka +++ b/doc/manual/cache/CompilerOptw.wakka @@ -2,13 +2,15 @@ Set minimum warning level. {{fbdoc item="syntax"}}## - **-w** //level// | **all** | **param** | **escape** | **pedantic** | **next** | **constness** + **-w** //level// | **all** | **none** | **param** | **escape** | **pedantic** | **next** | **funcptr** | **constness** ## {{fbdoc item="param"}} ##//level//## - Warning messages only with a level equal or greater to this value will be output. + Warning messages only with a level equal or greater to this value will be output. ##**all**## - Equivalent to specifying a ##//level//## of zero (##0##). + Equivalent to specifying a ##//level//## of negative one (##-1##). + ##**none**## + Suppresses all warnings. ##**param**## Warn when procedure parameters aren't specified with either ##[[KeyPgByval|ByVal]]## or ##[[KeyPgByref|ByRef]]##. ##**escape**## @@ -17,16 +19,20 @@ Set minimum warning level. Equivalent to specifying the ##**param**## and ##**escape**## arguments, plus length checking of parameters passed ##[[KeyPgByval|ByVal]]## and of any ##[[KeyPgCptr|Cptr]]## converting to pointer only. ##**next**## Warn when ##[[KeyPgNext|Next]]## is followed by an identifier. + ##**funcptr**## + Warn on mismatched procedure pointers, including conversions in ##[[KeyPgCast|CAST]]## and ##[[KeyPgCptr|CPTR]]## expressions. Implies '-w all'. Experimental. Behaviour may change in future versions. ##**constness**## - Warn when ##[[KeyPgConstQualifier|CONST (Qualifier)]]## is discarded in an assignment. + Warn when ##[[KeyPgConstQualifier|CONST (Qualifier)]]## is discarded in an assignment. Implies '-w funcptr' and '-w all'. Behaviour may change in future versions. {{fbdoc item="desc"}} - The ##-w## compiler option determines which compiler warnings, if any, are output. Each possible warning is associated with a warning level, starting from zero (##0##) and increasing with the potential problems that may occur. A significantly high ##//level//## value will have the effect of suppressing all warning messages. + The ##-w## compiler option determines which compiler warnings, if any, are output. Each possible warning is associated with a warning level, starting from negative one (##-1##) and increasing with the potential problems that may occur. - Note that the ##**param**##, ##**escape**##, ##**pedantic**##, ##**next**## and ##**constness**## arguments provide additional warnings not ordinarily output, even by default. + The ##**param**##, ##**escape**##, ##**pedantic**##, ##**next**##, ##**funcptr**##, and ##**constness**## arguments provide additional warnings not ordinarily output, even by default. + + The default, if the ##**-w**## option is not specified, is as if ##**-w 0**## was used. The ##**-w**## option can be specified multiple times. Warning messages having a level of ##-1## are not shown by default. + + ##-w none##, or a significantly high ##//level//## value will have the effect of suppressing all warning messages. - If the ##**-w**## option is not specified, it's as if ##**-w 0**## was used. The ##**-w**## option can be specified multiple times. - {{fbdoc item="see"}} - [[CompilerCmdLine|Using the Command Line]] diff --git a/doc/manual/cache/ExtLibaspell.wakka b/doc/manual/cache/ExtLibaspell.wakka index a2dacc4acb..e9d31c0c79 100644 --- a/doc/manual/cache/ExtLibaspell.wakka +++ b/doc/manual/cache/ExtLibaspell.wakka @@ -10,44 +10,44 @@ Header version: 0.60.6.1 {{fbdoc item="filename" value="examples/manual/libraries/aspell.bas"}}%%(freebasic) '' GNU-ASspell example, converted from http://aspell.net/win32/ -#include once "aspell.bi" +#include Once "aspell.bi" -dim as AspellConfig ptr spell_config = new_aspell_config() +Dim As AspellConfig Ptr spell_config = new_aspell_config() '' Change this to suit the installed dictionary language if desired aspell_config_replace(spell_config, "lang", "en_CA") '' Create speller object -dim as AspellCanHaveError ptr possible_err = new_aspell_speller(spell_config) -if (aspell_error_number(possible_err) <> 0) then - print *aspell_error_message(possible_err) - end 1 -end if -dim as AspellSpeller ptr speller = to_aspell_speller(possible_err) - -dim as string word -do - print - input "Enter a word (blank to quit): ", word - if (len(word) = 0) then - exit do - end if - - if (aspell_speller_check(speller, strptr(word), len(word)) <> 0) then - print "Word is Correct" - else - print "Suggestions:" - dim as AspellStringEnumeration ptr elements = _ - aspell_word_list_elements(aspell_speller_suggest(speller, strptr(word), len(word))) - do - dim as zstring ptr w = aspell_string_enumeration_next(elements) - if (w = 0) then - exit do - end if - print " "; *w - loop +Dim As AspellCanHaveError Ptr possible_err = new_aspell_speller(spell_config) +If (aspell_error_number(possible_err) <> 0) Then + Print *aspell_error_message(possible_err) + End 1 +End If +Dim As AspellSpeller Ptr speller = to_aspell_speller(possible_err) + +Dim As String word +Do + Print + Input "Enter a word (blank to quit): ", word + If (Len(word) = 0) Then + Exit Do + End If + + If (aspell_speller_check(speller, StrPtr(word), Len(word)) <> 0) Then + Print "Word is Correct" + Else + Print "Suggestions:" + Dim As AspellStringEnumeration Ptr elements = _ + aspell_word_list_elements(aspell_speller_suggest(speller, StrPtr(word), Len(word))) + Do + Dim As const ZString Ptr w = aspell_string_enumeration_next(elements) + If (w = 0) Then + Exit Do + End If + Print " "; *w + Loop delete_aspell_string_enumeration(elements) - end if + End If ' - Report the replacement 'aspell_speller_store_repl(speller, misspelled_word, size, @@ -55,7 +55,7 @@ do ' - Add to session or personal dictionary 'aspell_speller_add_to_session|personal(speller, word, size) -loop +Loop delete_aspell_speller(speller) %% diff --git a/doc/manual/cache/ExtLibcryptlib.wakka b/doc/manual/cache/ExtLibcryptlib.wakka index 3eca340d10..e104c2b977 100644 --- a/doc/manual/cache/ExtLibcryptlib.wakka +++ b/doc/manual/cache/ExtLibcryptlib.wakka @@ -9,70 +9,70 @@ Examples: in examples/math/cryptlib/ {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/libraries/cryptlib.bas"}}%%(freebasic) -#include once "cryptlib.bi" +#include Once "cryptlib.bi" -function calc_hash( byval filename as string, byval algo as CRYPT_ALGO_TYPE ) as string - const BUFFER_SIZE = 8192 - dim as byte buffer( 0 to BUFFER_SIZE-1 ) +Function calc_hash( ByVal filename As String, ByVal algo As CRYPT_ALGO_TYPE ) As String + Const BUFFER_SIZE = 8192 + Dim As Byte buffer( 0 To BUFFER_SIZE-1 ) '' create a new context using the wanted algorithm - dim as CRYPT_CONTEXT ctx + Dim As CRYPT_CONTEXT ctx cryptCreateContext( @ctx, CRYPT_UNUSED, algo ) '' open input file in binary mode - dim as integer f = freefile() - if( open( filename for binary access read as #f ) <> 0 ) then - return "" - end if + Dim As Integer f = FreeFile() + If( Open( filename For Binary Access Read As #f ) <> 0 ) Then + Return "" + End If '' read until end-of-file - do until( eof( f ) ) - dim as integer oldpos = seek( f ) - get #f, , buffer() - dim as integer readlength = seek( f ) - oldpos + Do Until( EOF( f ) ) + Dim As Integer oldpos = Seek( f ) + Get #f, , buffer() + Dim As Integer readlength = Seek( f ) - oldpos '' encrypt cryptEncrypt( ctx, @buffer(0), readlength ) - loop + Loop '' close input file - close #f + Close #f '' finalize cryptEncrypt( ctx, 0, 0 ) '' get the hash result - dim as integer buffersize = BUFFER_SIZE + Dim As Integer buffersize = BUFFER_SIZE cryptGetAttributeString( ctx, CRYPT_CTXINFO_HASHVALUE, @buffer(0), @buffersize ) '' convert to hexadecimal - dim as string result = "" - for i as integer = 0 to buffersize-1 - result += hex( buffer(i) ) - next + Dim As String result = "" + For i As Integer = 0 To buffersize-1 + result += Hex( buffer(i) ) + Next '' free the context cryptDestroyContext( ctx ) - return result -end function + Return result +End Function - dim as string filename = trim( command(1) ) - if( len( filename ) = 0 ) then - print "Usage: hash.exe filename" - end -1 - end if + Dim As String filename = Trim( Command(1) ) + If( Len( filename ) = 0 ) Then + Print "Usage: hash.exe filename" + End -1 + End If '' init cryptlib cryptInit( ) '' calculate hashes - print "md5: "; calc_hash( filename, CRYPT_ALGO_MD5 ) - print "sha: "; calc_hash( filename, CRYPT_ALGO_SHA ) + Print "md5: "; calc_hash( filename, CRYPT_ALGO_MD5 ) + Print "sha1: "; calc_hash( filename, CRYPT_ALGO_SHA1 ) '' shutdown cryptlib cryptEnd( ) - sleep + Sleep %% {{fbdoc item="back" value="ExtLibTOC|External Library Table of Contents"}} diff --git a/doc/manual/cache/ExtLibexpat.wakka b/doc/manual/cache/ExtLibexpat.wakka index 7120d5d253..27cf4d4a90 100644 --- a/doc/manual/cache/ExtLibexpat.wakka +++ b/doc/manual/cache/ExtLibexpat.wakka @@ -14,121 +14,124 @@ Examples: in examples/xml/ '' Can use zstring or wstring (libexpat or libexpatw): '#define XML_UNICODE -#include once "expat.bi" +#include Once "expat.bi" +#include Once "crt/mem.bi" -#define FALSE 0 +#ifndef False +#define False 0 +#endif #define NULL 0 -const BUFFER_SIZE = 1024 +Const BUFFER_SIZE = 1024 -type Context - as integer nesting - as XML_char * (BUFFER_SIZE+1) text - as integer textlength -end type +Type Context + As Integer nesting + As XML_char * (BUFFER_SIZE+1) text + As Integer textlength +End Type -dim shared as Context ctx +Dim Shared As Context ctx '' Callback called by libexpat when begin of XML tag is found -sub elementBegin cdecl _ +Sub elementBegin cdecl _ ( _ - byval userdata as any ptr, _ - byval element as XML_char ptr, _ - byval attributes as XML_char ptr ptr _ + ByVal userdata As Any Ptr, _ + ByVal element As const XML_char Ptr, _ + ByVal attributes As const XML_char Ptr Ptr _ ) '' Show its name - print space(ctx.nesting);*element; + Print Space(ctx.nesting);*element; '' and its attributes (attributes are given as an array of XML_char pointers '' much like argv, for each attribute there will apparently be the one '' element representing the name and a second element representing the '' specified value) - while (*attributes) - print " ";**attributes; + While (*attributes) + Print " ";**attributes; attributes += 1 - print "='";**attributes;"'"; + Print "='";**attributes;"'"; attributes += 1 - wend - print + Wend + Print ctx.nesting += 1 ctx.text[0] = 0 ctx.textlength = 0 -end sub +End Sub '' Callback called by libexpat when end of XML tag is found -sub elementEnd cdecl(byval userdata as any ptr, byval element as XML_char ptr) +Sub elementEnd cdecl(ByVal userdata As Any Ptr, ByVal element As const XML_char Ptr) '' Show text collected in charData() callback below - print space(ctx.nesting);ctx.text + Print Space(ctx.nesting);ctx.text ctx.text[0] = 0 ctx.textlength = 0 ctx.nesting -= 1 -end sub +End Sub -sub charData cdecl _ +Sub charData cdecl _ ( _ - byval userdata as any ptr, _ - byval chars as XML_char ptr, _ '' Note: not null-terminated - byval length as integer _ + ByVal userdata As Any Ptr, _ + ByVal chars As const XML_char Ptr, _ '' Note: not null-terminated + ByVal length As Integer _ ) '' This callback will apparently recieve every data between xml tags '' (really?), including newlines and space. '' Append to our buffer, if there still is free room, so we can print it out later - if (length <= (BUFFER_SIZE - ctx.textlength)) then - fb_MemCopy(ctx.text[ctx.textlength], chars[0], length * sizeof(XML_char)) + If (length <= (BUFFER_SIZE - ctx.textlength)) Then + memcpy(@ctx.text[ctx.textlength], @chars[0], length * SizeOf(XML_char)) ctx.textlength += length ctx.text[ctx.textlength] = 0 - end if -end sub + End If +End Sub '' '' Main '' - dim as string filename = command(1) - if (len(filename) = 0) then - print "Usage: expat " - end 1 - end if + Dim As String filename = Command(1) + If (Len(filename) = 0) Then + Print "Usage: expat " + End 1 + End If - dim as XML_Parser parser = XML_ParserCreate(NULL) - if (parser = NULL) then - print "XML_ParserCreate failed" - end 1 - end if + Dim As XML_Parser parser = XML_ParserCreate(NULL) + If (parser = NULL) Then + Print "XML_ParserCreate failed" + End 1 + End If ''XML_SetUserData(parser, userdata_pointer) XML_SetElementHandler(parser, @elementBegin, @elementEnd) XML_SetCharacterDataHandler(parser, @charData) - if (open(filename, for input, as #1)) then - print "Could not open file: '";filename;"'" - end 1 - end if + If (Open(filename, For Input, As #1)) Then + Print "Could not open file: '";filename;"'" + End 1 + End If - static as ubyte buffer(0 to (BUFFER_SIZE-1)) + Static As UByte buffer(0 To (BUFFER_SIZE-1)) - dim as integer reached_eof = FALSE - do - dim as integer size = BUFFER_SIZE - dim as integer result = get(#1, , buffer(0), size, size) - if (result or (size <= 0)) then - print "File input error" - end 1 - end if + Dim As Integer reached_eof = False + Do + Dim As Integer size = BUFFER_SIZE + Dim As Integer result = Get(#1, , buffer(0), size, size) + If (result Or (size <= 0)) Then + Print "File input error" + End 1 + End If - reached_eof = (eof(1) <> FALSE) + reached_eof = (EOF(1) <> False) - if (XML_Parse(parser, @buffer(0), size, reached_eof) = FALSE) then - print filename & "(" & XML_GetCurrentLineNumber(parser) & "): Error from XML parser: " - print *XML_ErrorString(XML_GetErrorCode(parser)) - end 1 - end if - loop while (reached_eof = FALSE) + If (XML_Parse(parser, @buffer(0), size, reached_eof) = False) Then + Print filename & "(" & XML_GetCurrentLineNumber(parser) & "): Error from XML parser: " + Print *XML_ErrorString(XML_GetErrorCode(parser)) + End 1 + End If + Loop While (reached_eof = False) XML_ParserFree(parser) %% diff --git a/doc/manual/cache/ExtLiblibxml.wakka b/doc/manual/cache/ExtLiblibxml.wakka index d8b9ad3f26..9d09719974 100644 --- a/doc/manual/cache/ExtLiblibxml.wakka +++ b/doc/manual/cache/ExtLiblibxml.wakka @@ -9,27 +9,27 @@ Examples: in examples/xml/ {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/libraries/libxml.bas"}}%%(freebasic) -#include once "libxml/xmlreader.bi" +#include Once "libxml/xmlreader.bi" #define NULL 0 -dim as string filename = command(1) -if( len( filename ) = 0 ) then - print "Usage: libxml filename" - end 1 -end if +Dim As String filename = Command(1) +If( Len( filename ) = 0 ) Then + Print "Usage: libxml filename" + End 1 +End If -dim as xmlTextReaderPtr reader = xmlReaderForFile( filename, NULL, 0 ) -if (reader = NULL) then - print "Unable to open "; filename - end 1 -end if +Dim As xmlTextReaderPtr reader = xmlReaderForFile( filename, NULL, 0 ) +If (reader = NULL) Then + Print "Unable to open "; filename + End 1 +End If -dim as integer ret = xmlTextReaderRead( reader ) -do while( ret = 1 ) - dim as zstring ptr constname = xmlTextReaderConstName( reader ) - dim as zstring ptr value = xmlTextReaderConstValue( reader ) +Dim As Integer ret = xmlTextReaderRead( reader ) +Do While( ret = 1 ) + Dim As const ZString Ptr constname = xmlTextReaderConstName( reader ) + Dim As const ZString Ptr value = xmlTextReaderConstValue( reader ) - print xmlTextReaderDepth( reader ); _ + Print xmlTextReaderDepth( reader ); _ xmlTextReaderNodeType( reader ); _ " "; *constname; _ xmlTextReaderIsEmptyElement(reader); _ @@ -37,13 +37,13 @@ do while( ret = 1 ) *value ret = xmlTextReaderRead( reader ) -loop +Loop xmlFreeTextReader( reader ) -if( ret <> 0 ) then - print "failed to parse: "; filename -end if +If( ret <> 0 ) Then + Print "failed to parse: "; filename +End If xmlCleanupParser( ) xmlMemoryDump() diff --git a/doc/manual/cache/KeyPgInkey.wakka b/doc/manual/cache/KeyPgInkey.wakka index bedf62d4f7..ff237f9961 100644 --- a/doc/manual/cache/KeyPgInkey.wakka +++ b/doc/manual/cache/KeyPgInkey.wakka @@ -27,6 +27,10 @@ do loop until inkey = "q" %% {{fbdoc item="filename" value="examples/manual/input/inkeyext.bas"}}%%(freebasic) +'' Compile with -lang fblite or qb + +#lang "fblite" + #if __FB_LANG__ = "qb" #define EXTCHAR Chr$(0) #else diff --git a/doc/manual/cache/KeyPgOpCombineModulus.wakka b/doc/manual/cache/KeyPgOpCombineModulus.wakka index 0acf19ba74..e2da4f97b7 100644 --- a/doc/manual/cache/KeyPgOpCombineModulus.wakka +++ b/doc/manual/cache/KeyPgOpCombineModulus.wakka @@ -36,7 +36,7 @@ SLEEP - New to ""FreeBASIC"" {{fbdoc item="see"}} - - ##[[KeyPgOpModulus|Operator + (Modulus)]]## + - ##[[KeyPgOpModulus|Operator Mod (Modulus)]]## - [[CatPgMath|Mathematical Functions]] {{fbdoc item="back" value="CatPgOpAssignment|Assignment Operators"}}{{fbdoc item="back" value="CatPgOperators|Operators"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgOpNewOverload.wakka b/doc/manual/cache/KeyPgOpNewOverload.wakka index 1fe65e7337..6caf44d4c5 100644 --- a/doc/manual/cache/KeyPgOpNewOverload.wakka +++ b/doc/manual/cache/KeyPgOpNewOverload.wakka @@ -99,34 +99,33 @@ Sleep %%(freebasic) Type UDTmanager '' user UDT fields: - Dim As Byte b(1 to 1024*1024) + Dim As Byte b(1 To 1024*1024) '' manager fields: Public: - Declare Operator New[] (Byval size As Uinteger) As Any Ptr - Declare Operator Delete[] (Byval buf As Any Ptr) - Static As Uinteger maxmemory + Declare Operator New[] (ByVal size As UInteger) As Any Ptr + Declare Operator Delete[] (ByVal buf As Any Ptr) + Static As UInteger maxmemory Private: Static As Any Ptr address() - Static As Uinteger bytes() - Static upbound As Uinteger - Declare Static Function printLine (Byref text As String, Byval index As Uinteger, Byval sign As Integer) As Uinteger + Static As UInteger bytes() + Static upbound As UInteger + Declare Static Function printLine (ByRef text As String, ByVal index As UInteger, ByVal sign As Integer) As UInteger Declare Static Sub endProgram () End Type -Dim As Uinteger UDTmanager.maxmemory = 3 * 1024 * 1024 * 1024 -Redim UDTmanager.address(0) -Redim UDTmanager.bytes(0) -Dim UDTmanager.upbound As Uinteger = 0 +Dim As UInteger UDTmanager.maxmemory = 3 * 1024 * 1024 * 1024 +ReDim UDTmanager.address(0) +ReDim UDTmanager.bytes(0) +Dim UDTmanager.upbound As UInteger = 0 -Function UDTmanager.printLine (Byref text As String, Byval index As Uinteger, Byval sign As Integer) As Uinteger +Function UDTmanager.printLine (ByRef text As String, ByVal index As UInteger, ByVal sign As Integer) As UInteger Dim As UInteger total = 0 - For I As Uinteger = 1 To UDTmanager.upbound + For I As UInteger = 1 To UDTmanager.upbound If I <> index Orelse Sgn(sign) > 0 Then total += UDTmanager.bytes(I) End If Next I - Print text, "&h"; - Print Hex(UDTmanager.address(index), Sizeof(Any Ptr) * 2), + Print text, "&h" & Hex(UDTmanager.address(index), SizeOf(Any Ptr) * 2), If sign <> 0 Then Print Using " +####.## MB"; Sgn(sign) * Cast(Integer, UDTmanager.bytes(index) / 1024) / 1024; Else @@ -142,8 +141,8 @@ Sub UDTmanager.endProgram () Deallocate UDTmanager.address(UDTmanager.upbound) UDTmanager.printLine("memory deallocation forced", UDTmanager.upbound, -1) UDTmanager.upbound -= 1 - Redim Preserve UDTmanager.address(UDTmanager.upbound) - Redim Preserve UDTmanager.bytes(UDTmanager.upbound) + ReDim Preserve UDTmanager.address(UDTmanager.upbound) + ReDim Preserve UDTmanager.bytes(UDTmanager.upbound) Loop Print "end program forced" Print @@ -151,12 +150,12 @@ Sub UDTmanager.endProgram () End End Sub -Operator UDTmanager.New[] (Byval size As Uinteger) As Any Ptr +Operator UDTmanager.New[] (ByVal size As UInteger) As Any Ptr Dim As Any Ptr p = Allocate(size) If p > 0 Then UDTmanager.upbound += 1 - Redim Preserve UDTmanager.address(UDTmanager.upbound) - Redim Preserve UDTmanager.bytes(UDTmanager.upbound) + ReDim Preserve UDTmanager.address(UDTmanager.upbound) + ReDim Preserve UDTmanager.bytes(UDTmanager.upbound) UDTmanager.address(UDTmanager.upbound) = p UDTmanager.bytes(UDTmanager.upbound) = size If UDTmanager.printLine("memory allocation", UDTmanager.upbound, +1) > UDTmanager.maxmemory Then @@ -176,19 +175,19 @@ Operator UDTmanager.New[] (Byval size As Uinteger) As Any Ptr End If End Operator -Operator UDTmanager.Delete[] (Byval buf As Any Ptr) - Dim As Uinteger found = 0 - For I As Uinteger = 1 To UDTmanager.upbound +Operator UDTmanager.Delete[] (ByVal buf As Any Ptr) + Dim As UInteger found = 0 + For I As UInteger = 1 To UDTmanager.upbound If UDTmanager.address(I) = buf Then Deallocate buf UDTmanager.printLine("memory deallocation", I, -1) - For J As Uinteger = I + 1 To UDTmanager.upbound + For J As UInteger = I + 1 To UDTmanager.upbound UDTmanager.address(J - 1) = UDTmanager.address(J) UDTmanager.bytes(J - 1) = UDTmanager.bytes(J) Next J UDTmanager.upbound -= 1 - Redim Preserve UDTmanager.address(UDTmanager.upbound) - Redim Preserve UDTmanager.bytes(UDTmanager.upbound) + ReDim Preserve UDTmanager.address(UDTmanager.upbound) + ReDim Preserve UDTmanager.bytes(UDTmanager.upbound) found = 1 Exit For End If @@ -201,7 +200,7 @@ Operator UDTmanager.Delete[] (Byval buf As Any Ptr) End Operator -Print "Message",, "Address"& Space(Sizeof(Any Ptr)), "Size", "Total" +Print "Message",, "Address" & Space(SizeOf(Any Ptr)), "Size", "Total" Print Randomize Dim As UDTmanager Ptr pu1 = New UDTmanager[Rnd() * 256 + 1] diff --git a/doc/manual/cache/KeyPgPcopy.wakka b/doc/manual/cache/KeyPgPcopy.wakka index 9d75f0a89c..503a0b7a60 100644 --- a/doc/manual/cache/KeyPgPcopy.wakka +++ b/doc/manual/cache/KeyPgPcopy.wakka @@ -49,6 +49,10 @@ Sleep %% {{fbdoc item="filename" value="examples/manual/gfx/pcopy_cons.bas"}}%%(freebasic) +'' Compile with -lang fblite or qb + +#lang "fblite" + '' Console mode example: '' Set the working page number to 0, and the visible page number to 1 diff --git a/doc/manual/cache/KeyPgPragma.wakka b/doc/manual/cache/KeyPgPragma.wakka index 51a4abff38..b176844ff3 100644 --- a/doc/manual/cache/KeyPgPragma.wakka +++ b/doc/manual/cache/KeyPgPragma.wakka @@ -19,6 +19,8 @@ Preprocessor directive Allows the setting of compiler options inside the source code. **Push** saves the current value of the //option// onto a stack, then assigns the new //value// (or //-1//) to it. **Pop** restores the //option// to its previous value, and removes it from the stack. This mechanism allows options to be changed for a certain part of source code, regardless of the setting used by the context, which is especially useful inside #include header files. + + **##constness##** pragma is added for testing fbc compiler. It will be removed in future at should not be relied upon. {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/prepro/pragma.bas"}}%%(freebasic) diff --git a/doc/manual/cache/ProPgFixLenArrays.wakka b/doc/manual/cache/ProPgFixLenArrays.wakka index ca1f625ce5..e5d51ccf51 100644 --- a/doc/manual/cache/ProPgFixLenArrays.wakka +++ b/doc/manual/cache/ProPgFixLenArrays.wakka @@ -22,12 +22,12 @@ static arrayOfShorts(420) as short There are various ways to specify an array's amount of elements. Each array can have between 1 or 8 dimensions. Each dimension has a lower bound and an upper bound. {{fbdoc item="filename" value="examples/manual/proguide/arrays/fixedlen_bounds.bas"}}%%(freebasic) -dim a(1) as integer '' 1-dimensional, 2 elements (0 and 1) -dim b(0 to 1) as integer '' 1-dimensional, 2 elements (0 and 1) -dim c(5 to 10) as integer '' 1-dimensional, 5 elements (5, 6, 7, 8, 9 and 10) +Dim a(1) As Integer '' 1-dimensional, 2 elements (0 and 1) +Dim b(0 To 1) As Integer '' 1-dimensional, 2 elements (0 and 1) +Dim c(5 To 10) As Integer '' 1-dimensional, 5 elements (5, 6, 7, 8, 9 and 10) -dim d(1 to 2, 1 to 2) as integer '' 2-dimensional, 4 elements: (1,1), (1,2), (2,1), (2,2) -dim e(255, 255, 255, 255) as integer '' 4-dimensional, 256 * 256 * 256 * 256 elements +Dim d(1 To 2, 1 To 2) As Integer '' 2-dimensional, 4 elements: (1,1), (1,2), (2,1), (2,2) +Dim e(99, 99, 99, 99) As Integer '' 4-dimensional, 100 * 100 * 100 * 100 elements %% For an array to be declared fixed-length, the boundaries must be specified using only number literals or ##[[KeyPgConst|Const]]## values or ##[[KeyPgEnum|Enum]]## constants.