fbc-ng
fbc-ng
FreeBASIC Compiler next generation is a project that will add sound and other game dev functions to FreeBASIC.
Re: fbc-ng
Having a bit of trouble... I have added a function to the source code(in rtl-gfx.bas). I compiled it all, and the function isn't working! How do I add a new keyword to FreeBASIC?
-
- Posts: 1006
- Joined: Nov 24, 2011 19:49
- Location: France
- Contact:
Re: fbc-ng
Hello !
chrowle wrote:FreeBASIC Compiler next generation is a project that will add sound and other game dev functions to FreeBASIC.
It's a joke, isn't it ?chrowle wrote:How do I add a new keyword to FreeBASIC?
Re: fbc-ng
No... Not a glorious moment..
Re: fbc-ng
What other game dev functions do you have in mind? And if you want to add new commands to freebasic thatchrowle wrote:FreeBASIC Compiler next generation is a project that will add sound and other game dev functions to FreeBASIC.
resemble functions that look like LINE, CIRCLE etc... then you'll have to add code in several places.
As an example of what should be done just take a look at
https://github.com/freebasic/fbc/blob/m ... rk-gfx.bas
You'll see something that looks like
Code: Select all
function cGfxStmt _
( _
byval tk as FB_TOKEN _
) as integer
function = FALSE
select case as const tk
case FB_TK_PSET
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxPSet( FALSE )
case FB_TK_PRESET
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxPSet( TRUE )
case FB_TK_LINE
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxLine( )
case FB_TK_CIRCLE
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxCircle( )
case FB_TK_PAINT
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxPaint( )
case FB_TK_DRAW
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxDraw( )
case FB_TK_VIEW
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxView( TRUE )
case FB_TK_WINDOW
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxView( FALSE )
case FB_TK_PALETTE
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxPalette( )
case FB_TK_PUT
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxPut( )
case FB_TK_GET
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxGet( )
case FB_TK_SCREEN
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxScreen( FALSE )
case FB_TK_SCREENQB
CHECK_CODEMASK( )
lexSkipToken( )
function = cGfxScreen( TRUE )
end select
end function
that parses that particular command. In case of graphics those commands would be
PSET, LINE etc...
So first thing to do would be to come up with appropriate syntax for the
new commands you want to add.
If you want to add functions that implement the new sound commands
you have to add lines to
https://github.com/freebasic/fbc/blob/m ... ler/rtl.bi
At the top of that file you'll find
'' NOTE: when adding any RTL proc that will be called from rtl*.bas,
'' always update the FB_RTL_IDX enum below
Now for those keywords. Have a look at
https://github.com/freebasic/fbc/blob/m ... r/fbint.bi
You'll find an enum called FB_TOKEN. You'll have to add entries
for the commands you are going to add. It's mostly the first word of the command
that matters here but if your commands contain other words that should
be recognized as something other than an identifer they should be
added to the enum as well. Not updating the enum appropriately will lead
to parsing problems.
Next up is the file
https://github.com/freebasic/fbc/blob/m ... eyword.bas
There is a shared variable that reads
Code: Select all
dim shared kwdTb( 0 to FB_TOKENS-1 ) as SYMBKWD => _
earlier.
I'll take one entry from kwdTB to show the kind of line you most likely want to add
Code: Select all
( @"CIRCLE" , FB_TK_CIRCLE , FB_TKCLASS_QUIRKWD ), _
Code: Select all
( @"PLAY" , FB_TK_PLAY , FB_TKCLASS_QUIRKWD,KWD_OPTION_NO_QB ), _
For any command you want to add you have to
--> add a token to enum FB_TOKEN
--> add an entry to kwdTb
--> implement a parsing function
And you need to create parser-quirk-sound.bas. There you will put all the parsing
functions for the commands you want to add to FreeBASIC.
Each of those parsing functions will call a function that (ultimately) makes
sure the appropriate function call is added to the generated source code (be it
assembler, C or something else).
You should also create a file called rtl-sound.bas with a content similar to that of other
rtl-xxx.bas files (rtl-string.bas, rtl-math.bas being examples of what rtl-sound.bas
should contain).
Having done all of the above you have to write the functions associated with the
commands. And you have to add code to
https://github.com/freebasic/fbc/blob/m ... -quirk.bas
Add a case line for each new keyword to the case statement in cQuirkStmt
Code: Select all
function cQuirkStmt _
( _
byval tk as FB_TOKEN = INVALID _
) as integer
function = FALSE
if( tk = INVALID ) then
tk = lexGetToken( )
select case lexGetClass( )
case FB_TKCLASS_KEYWORD, FB_TKCLASS_QUIRKWD
'' QB mode?
if( env.clopt.lang = FB_LANG_QB ) then
if( lexGetType() <> FB_DATATYPE_INVALID ) then
return FALSE
end if
end if
case else
if( tk = CHAR_QUESTION ) then '' PRINT as '?', can't be a keyword..
CHECK_CODEMASK( )
function = cPrintStmt( tk )
end if
exit function
end select
end if
dim as integer res = FALSE
select case as const tk
case FB_TK_GOTO, FB_TK_GOSUB, FB_TK_RETURN, FB_TK_RESUME
CHECK_CODEMASK( )
res = cGotoStmt( tk )
case FB_TK_PRINT, FB_TK_LPRINT
CHECK_CODEMASK( )
res = cPrintStmt( tk )
case FB_TK_RESTORE, FB_TK_READ, FB_TK_DATA
CHECK_CODEMASK( )
res = cDataStmt( tk )
case FB_TK_ERASE
CHECK_CODEMASK( )
res = cEraseStmt()
case FB_TK_SWAP
CHECK_CODEMASK( )
res = cSwapStmt()
case FB_TK_LINE
CHECK_CODEMASK( )
res = cLineInputStmt( )
case FB_TK_INPUT
CHECK_CODEMASK( )
res = cInputStmt( )
case FB_TK_POKE
CHECK_CODEMASK( )
res = cPokeStmt( )
case FB_TK_OPEN, FB_TK_CLOSE, FB_TK_SEEK, FB_TK_PUT, FB_TK_GET, _
FB_TK_LOCK, FB_TK_UNLOCK, FB_TK_NAME
CHECK_CODEMASK( )
res = cFileStmt( tk )
case FB_TK_ON
CHECK_CODEMASK( )
res = cOnStmt( )
case FB_TK_WRITE
CHECK_CODEMASK( )
res = cWriteStmt()
case FB_TK_ERROR
CHECK_CODEMASK( )
res = cErrorStmt()
case FB_TK_ERR
CHECK_CODEMASK( )
res = cErrSetStmt()
case FB_TK_VIEW
CHECK_CODEMASK( )
res = (cViewStmt(FALSE) <> NULL)
case FB_TK_MID
CHECK_CODEMASK( )
res = cMidStmt( )
case FB_TK_LSET, FB_TK_RSET
CHECK_CODEMASK( )
res = cLRSetStmt( tk )
case FB_TK_WIDTH
CHECK_CODEMASK( )
res = cWidthStmt( FALSE ) <> NULL
case FB_TK_COLOR
CHECK_CODEMASK( )
res = cColorStmt( FALSE ) <> NULL
case FB_TK_REM
'' due the QB quirks..
if( env.clopt.lang = FB_LANG_QB ) then
res = cComment( )
end if
end select
if( res = FALSE ) then
res = cGfxStmt( tk )
end if
function = res
end function
'regular' functions then you have to add a case for the new commands to
Code: Select all
function cQuirkFunction(byval sym as FBSYMBOL ptr) as ASTNODE ptr
dim as ASTNODE ptr funcexpr = NULL
dim as FB_TOKEN tk = sym->key.id
select case as const tk
case FB_TK_MKD, FB_TK_MKS, FB_TK_MKI, FB_TK_MKL, _
FB_TK_MKSHORT, FB_TK_MKLONGINT
funcexpr = cMKXFunct(tk)
case FB_TK_CVD, FB_TK_CVS, FB_TK_CVI, FB_TK_CVL, _
FB_TK_CVSHORT, FB_TK_CVLONGINT
funcexpr = cCVXFunct(tk)
case FB_TK_STR, FB_TK_WSTR, FB_TK_MID, FB_TK_STRING, FB_TK_WSTRING, _
FB_TK_CHR, FB_TK_WCHR, _
FB_TK_ASC, FB_TK_INSTR, FB_TK_INSTRREV, _
FB_TK_TRIM, FB_TK_RTRIM, FB_TK_LTRIM, _
FB_TK_LCASE, FB_TK_UCASE
funcexpr = cStringFunct(tk)
case FB_TK_ABS, FB_TK_SGN, FB_TK_FIX, FB_TK_FRAC, FB_TK_LEN, FB_TK_SIZEOF, _
FB_TK_SIN, FB_TK_ASIN, FB_TK_COS, FB_TK_ACOS, FB_TK_TAN, FB_TK_ATN, _
FB_TK_SQR, FB_TK_LOG, FB_TK_EXP, FB_TK_ATAN2, FB_TK_INT
funcexpr = cMathFunct(tk, FALSE)
case FB_TK_PEEK
funcexpr = cPeekFunct()
case FB_TK_LBOUND, FB_TK_UBOUND
funcexpr = cArrayFunct(tk)
case FB_TK_SEEK, FB_TK_INPUT, FB_TK_WINPUT, FB_TK_OPEN, FB_TK_CLOSE, _
FB_TK_GET, FB_TK_PUT, FB_TK_NAME
funcexpr = cFileFunct(tk)
case FB_TK_ERR
funcexpr = cErrorFunct()
case FB_TK_IIF
return cStrIdxOrMemberDeref( cIIFFunct( ) )
case FB_TK_VA_FIRST
funcexpr = cVAFunct()
case FB_TK_CBYTE, FB_TK_CSHORT, FB_TK_CINT, FB_TK_CLNG, FB_TK_CLNGINT, _
FB_TK_CUBYTE, FB_TK_CUSHORT, FB_TK_CUINT, FB_TK_CULNG, FB_TK_CULNGINT, _
FB_TK_CSNG, FB_TK_CDBL, FB_TK_CSIGN, FB_TK_CUNSG
return cTypeConvExpr( tk )
case FB_TK_TYPE
return cStrIdxOrMemberDeref( cAnonType( ) )
case FB_TK_VIEW
funcexpr = cViewStmt(TRUE)
case FB_TK_WIDTH
funcexpr = cWidthStmt( TRUE )
case FB_TK_COLOR
funcexpr = cColorStmt( TRUE )
case FB_TK_SCREEN, FB_TK_SCREENQB
funcexpr = cScreenFunct()
case FB_TK_THREADCALL
funcexpr = cThreadCallFunc()
end select
if( funcexpr = NULL ) then
funcexpr = cGfxFunct( tk )
end if
function = funcexpr
end function
FreeBASIC you have to add a few lines of code to several existing files, create
some BASIC files and (of course) implement whatever the command should
'do'.
Above all your code has so fit into the runtime library framework as (informally)
defined by the developers. You have a bit of freedom here and there when it
comes to implementation but overall the framework used forces you to do things
in a certain manner. Divert to much from the framework and your extension to
the rtlib will not work.
Having written all of the above I personally do not think it is worthwhile
to try and add functions to the freebasic runtime library.
Chances are your code will not make it into the fb runtime library.
But don't let my scepticism keep you from hacking the fb source code.
If you are able to create a working version of the fbc that includes your
extended version of the runtime library then that would be quite something.
Re: fbc-ng
It is the holographic (distributed) nature of the FreeBasic source code that prevents it being patched up to allow dynamic arrays in objects, isn't it?
Re: fbc-ng
No, usually it is the freeing. Anything dynamic must have a strategy to free memory when it goes out of scope etc. Usually reliable freeing and resizing also needs a form of reliable initialization. (e.g. a refcount)sean_vn wrote:It is the holographic (distributed) nature of the FreeBasic source code that prevents it being patched up to allow dynamic arrays in objects, isn't it?
This initialization is used to distinguish within a random (pointer) value due not being initialized and an initialized pointer value that must be resized (or freed)
Re: fbc-ng
Ok, that clarifies the situation.
Re: fbc-ng
Have you taken a look at what we have done with the Extended Library project? We don't have a sound module yet, but there is a ton of graphical and other functions/classes that would be useful for game development (and general development). I have thought about building a sound module around the excellent BASS library, but I would much prefer something that is open source as a base.chrowle wrote:FreeBASIC Compiler next generation is a project that will add sound and other game dev functions to FreeBASIC.
Re: fbc-ng
I would consider joining the project, if you made it support Linux.
EDIT: Never mind, seems to be compiling fine. How do I join?
EDIT: Never mind, seems to be compiling fine. How do I join?
Re: fbc-ng
Join me on IRC http://ext.freebasic.net/page/supportchrowle wrote:I would consider joining the project, if you made it support Linux.
EDIT: Never mind, seems to be compiling fine. How do I join?