Editing QB64 source
From QB64 Wiki
Galleon encourages members to help make QB64 better! Participation is open to all members to participate at their own pace.
- You get a membership by applying for one in this thread: http://www.qb64.net/forum/index.php?topic=10505.0 (as well as some basic information how to work with it).
- The code repository itself is located here: http://code.google.com/p/qb64/source/browse/
Tutorial by SMcNeill
As posted on QB64 forums, formatted to suit the Wiki by Cyperium.
The basic concept of adding things to QB64:
First, one must understand that there are 2 distinct portions of QB64. The first is QB64.bas which is the translator which turns our BAS code into a C++ output, and the other is the C-code which the g++ compiler links to to assemble our EXE files. To add any new commands, you'll need to actually work in both areas.
For starters, let's take a look inside QB64.bas. Make a copy of your source (call it QB64-Test.bas) and open it for editing.
The first thing to do is a quick search (F3) for "SUB removeelements". The actual sub we're working in is "SUB reginternal", but we want to go to the end of it and make our changes, and SUB removeelements is the one after it and all we'll need do is scroll up a bit.
So go to "SUB removeelements" and scroll up past the comments there, until you see the following:
clearid id.n = "LPOS" id.subfunc = 1 id.callname = "func_lpos" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid 'Change on 06/19/2014 by Steve to allow for easier additions to the Code Id without 'people having to come into the QB64.bas source directly and make changes. '$INCLUDE:'internal/source/User Mods/User Mod List.bi' reginternalsubfunc = 0
If you notice, there's an include there that we make use of so that you can write your own code outside the BAS source and not have to meddle in the main code so much, but I feel like it's best for people to know WHERE things are in QB64.bas so that they can use previous commands as a template for their own.
So, the easiest way to do this tutorial is just to actually ADD a command. Since ATN is already in QB64, I didn't create a _ATAN command like I did for the rest of the math.h commands. We're going to make one now!
In between that last regid and the comments, we're going to go in and add a command! For ease of use, copy the last command and paste it right in there so what you have looks like:
clearid id.n = "LPOS" id.subfunc = 1 id.callname = "func_lpos" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "LPOS" id.subfunc = 1 id.callname = "func_lpos" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid
Now to break things down step by step as we alter the code we just pasted.
- clearid --- this clears the old information and prepares up for a new QB64 keyword entry
- id.n = "LPOS" -- this IS the QB64 keyword. Let's change LPOS to _ATAN for the _ATAN command.
- id.subfunc = 1 -- Here we use 1 for FUNCTION, 2 for SUB. ATAN is a function, so we leave this 1.
- id.callname = "func_lpos" -- the C++ command name. We have to add new C commands into the C portion if they're not defined, but ATAN is defined in math.h, which we already connect to. Make the callname "atan"
- id.args = 1 -- How many arguments does our routine take. Let's see ATAN(num)... 1, so we'll leave this alone.
- id.arg = MKL$(LONGTYPE - ISPOINTER) -- what variable TYPE does the arguments need? ATAN needs floating point numbers, so change this to "MKL$(FLOATTYPE - ISPOINTER)".
- id.ret = LONGTYPE - ISPOINTER -- what variable TYPE do we expect to get back? Once again we expect to get back a float so make this "(FLOATTYPE - ISPOINTER)"
- id.NoCloud = 1 -- would this command work on the QLOUD? In this case, it should so leave it alone.
- regid -- and let's register our ID.
clearid id.n = "_ATAN" id.subfunc = 1 id.callname = "atan" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER id.NoCloud = 1 regid
Now, hit F5 to compile and run and take a nap. It takes a while for the source to compile. Once the window pops up, try the following:
PRINT _ATAN(1), ATN(1)
Congratulations!! You just added a command to QB64!! (One that was pre-existing in the C-code, but you've added one.) For the people concerned about the "bloating" of QB64 with a lot of the new math commands I added, THIS is all that was required. Now, how much bloat is that really? ;)
Now that you've added a command, let's take a look at that INCLUDE. The Include is our way of trying to keep things modular and to keep from doing anything that might damage the core functionality of QB64. If you go into internal/source/User Mods , you can see where both Luke and I have started our own files for included stuff. Feel free to open one up and look at it.
Instead of HAVING to go into QB64.bas and meddle in the core functions of QB64, I'd highly suggest that you make your own BI file and add to it in the User Mods area instead. This way we can easily test to see if someones new command broke something (Just remark out that INCLUDE and compile and PRESTO! No new commands registered.), and can easily track who added what and know where to go to find the proper person to help correct any issues that might pop up in the future.
Use QB64.bas as a template for what your command needs, but put your actual command into the User Mods folder. QB64 is complex enough already and needs to become more modular. Let's start HERE and continue the practice of modularizing things as we go along. :D
Now that we've covered how to add the command into QB64 itself, let's take a moment and talk about how to add a C command to the source.
We've REALLY simplified this process. If you look into any of the most recent dirty builds, you can go into the internal/c folder and see a folder there called "User Mods". (YES, QB64 has 2 User Mod folders. One for the QB64.BAS changes, and one for the C changes.)
In there you'll see 2 important files:
Users Routines-List.cpp and user_list.h
Add your name to those 2 lists, and feel free to add your C routines all you'd like. The CPP files are the actual C code, and the H files are the headers which describe them.
I'm not the world's best C programmer, so I assume that anyone wanting to add C commands probably know more about this side of the project than I do, and thus there's not too much I can explain rather than to point you to where to go to make your changes.
Once you've made the changes you like and added your own stuff, use the purge_all_precompiled_content.bat file so your changes take affect.
That's all it is to the C++ side of things!!
Now, tie those two lessons together, and you can start adding custom C routines into the source yourself. :D
FOR QUESTIONS AND HELP GO TO EITHER:
QB64 Forums Topic: http://www.qb64.net/forum/index.php?topic=11976.0
QB64 Chat: http://webchat.freenode.net Channel: #qb64