March 28, 2024, 06:47:56 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Is this CBasic related to this CBasic ?

Started by vmars316, January 25, 2013, 10:19:15 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

vmars316

- www.vmars316.com
"All things in moderation, except for love and forgiveness."

LarryMc

This is THE CBasic.
I  assume any reference is to this one.
What's your question?
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

GWS

That reference was a proposal by a new user 'parkovski' to develop a compiler for CBasic ..

Nothing more was heard of it - so I conclude it was not successful.

There is only one Creative Basic - the one available on this site.

best wishes, :)

Graham
Tomorrow may be too late ..

aurelCB


GWS

I've no idea.  I don't think anything happened after it was suggested.
It would have been quite some trick to make it work ..  ::)

Graham
Tomorrow may be too late ..

Parker

Hey everybody. I just came across this thread. I can't see the other linked thread so I'm not sure what I wrote there, but I did actually get a very limited CBasic/IBasic compiler working a couple years ago. When I say limited though, I mean that most of the very basic syntax works, but the harder to implement stuff does not, and there are no standard libraries.

However, if anyone is curious, or wants to work on it, it's available here: https://github.com/parkovski/glazc. You will need the latest release of LLVM, the boost C++ libraries, and a C++ compiler (Visual studio and GCC should both work).

It's called GlazBasic. Glaz is the Russian word for eye :).

aurelCB

Hi Parker..
So to compile this code we need
1.latest LLVM
2.boost C++ lib
3. Vc or MingW..
Do we can use Borland BCC32 compiler to?

aurelCB

And which one of LLVM is latest 3.2 it looks but i dont see on
download page any release for windows...anyone else see it ... ???

Parker

Ok, since you're interested, here is how to get this working. I apologize in advance for how complicated this is - unfortunately that's how C++ development is. And that's why we're trying to make a BASIC compiler :).

I've never used Borland. It may work, and it may not. I'm going to assume VC++ 2012 on Windows. I've also used GCC on Mac OS X, which I can give instructions for if anyone is interested - one of the reasons I started this is I thought it would be cool to have a Mac compatible IBasic.

Get the tools required to build
- Visual Studio 2012 Express for Windows Desktop (http://www.microsoft.com/visualstudio/eng/downloads). You may be able to use earlier versions. LLVM will not build with anything earlier than 2005.
- CMake is required to build LLVM. http://www.cmake.org/cmake/resources/software.html
- Python 2.7 is also required for LLVM. http://python.org/download/
- LLVM source: http://llvm.org/releases/download.html#3.2 (the top one - LLVM source code)
- Boost: http://sourceforge.net/projects/boost/files/boost/1.53.0/ (you won't have to build anything for this luckily - you just need the headers)

Configure and build LLVM
- You will need CMake installed. I used the command line for this part, but you may be able to use the GUI also.
- You'll set "where is the source code" to your LLVM folder (llvm-3.2.src)
- Click the configure button, and select your compiler. Pick 32 bit. I have not tested 64 bit on windows.
- Click generate.
- Alternately, you can use this command from your llvm-3.2.src directory: cmake -G "Visual Studio 11" (or whatever version you have - 2012 is v11, 2010 is v10)
- Open LLVM.sln in Visual Studio.
- Right click the ALL_BUILD project and click build. This will take a while.

Check out and build glazc
- You can either use git to clone the project from my github: git clone git://github.com/parkovski/glazc.git
- Or you can just download the zip file from https://github.com/parkovski/glazc
- Create a visual studio project file, and add all of the *.cpp and *.h files and scanner.c. Don't add ast-xml.cpp or llvmtest.cpp though - the first was a non-completed attempt to print an XML representation of the programs for debugging, and the second was just a simple test of the LLVM JIT that can be built on its own.
- Configure the includes and libraries. Right click the project (not solution) -> Properties -> Configuration Properties -> C/C++ -> Additional Include Directories. Add the path to your LLVM includes and boost. For me these are C:\Users\Parker\Documents\llvm-3.2.src\include and C:\Users\Parker\Documents\boost_1_53_0.
- Add library directories. Same screen as above Linker -> Additional Library Directories. Add your LLVM libs directory. For me it's C:\Users\Parker\Documents\llvm-3.2.src\lib\Debug.
- Add the LLVM libraries. There are a lot of them. Under Linker -> Input -> Additional Dependencies, add these:
LLVMAnalysis.lib
LLVMAsmPrinter.lib
LLVMCodeGen.lib
LLVMCore.lib
LLVMExecutionEngine.lib
LLVMInstCombine.lib
LLVMInterpreter.lib
LLVMipa.lib
LLVMipo.lib
LLVMJIT.lib
LLVMMC.lib
LLVMMCParser.lib
LLVMObject.lib
LLVMRuntimeDyld.lib
LLVMScalarOpts.lib
LLVMSelectionDAG.lib
LLVMSupport.lib
LLVMTarget.lib
LLVMTransformUtils.lib
LLVMX86AsmPrinter.lib
LLVMX86CodeGen.lib
LLVMX86Desc.lib
LLVMX86Info.lib
LLVMX86Utils.lib

- Save properties, and press F7 to build. You'll get some warnings from the LLVM headers but hopefully no errors.
- Create a test source file. If you put this in the same place as your VS project file and call it test.gb, the compiler will find it automatically. Because I haven't gotten very far with this project, you can't really use any BASIC commands - you have to import things from the C runtime library. Here is a simple hello world program:
declare "",puts(fmt:char*),int
' yeah, sorry, the string type and print don't even work yet.

puts "hello world!"


There are many tens and possibly a couple hundred hours more work before this would be a viable development environment comparable to something from IW. I'll try to upload a mini text adventure game that runs in GB though if I can find it.

Parker

So I figured I'd write out a description of how the compiler works, just in case anybody comes along and wants to work on it.

Everything starts in main.cpp, which handles some command line options. One of the options prints a parse tree, which is useful for debugging sometimes, but confusing otherwise. In most cases though, we create a Parser, and then generate a Component (this is analogous to an IBasic/CBasic component). Then we compile the component's main function and call it.

Scanner (scanner.re)
You probably won't need to change the scanner much, but if you do, the actual code is in scanner.re, and it's compiled to scanner.c by re2c. Re2c is supposed to be fast, but it's also complicated and has very little documentation, so I wouldn't try to mess with the code that reads parts of a file. It keeps a bajillion pointers to different things and I don't really remember what they all do. If you need to add any keywords or other syntax, that will happen inside of the scan(Scanner*, SourceLocation*) function. Some high level constructs need tokens that don't exist in the actual source code - you use token_from_text for this. token_free will free a token and all its children. token_free_all will free a list of tokens and all their children.

Parser (parser.cpp)
It's hand-written recursive descent with an operator precedence part for expressions. I tried to put the grammar that each function handles as a comment before it, but I probably missed some. It creates a parse tree which is basically a linked list where each node can have a child that is also a mini parse tree. If you make changes to this, you may want to use the -emit:parsetree option to verify your work. If you search for "case WAITUNTIL" in parser.cpp you can see a tiny example of how to construct the parse tree for the WAITUNTIL statement.

AST builder (ast-build.cpp, ast-pass2.cpp)
This is done in 2 passes in order to auto-declare subs, similar to IBasic Pro. I saw a post talking about how IBasic doesn't have real subroutines, which is true, and makes this hard. The logic I used is, if it says "sub", it is a subroutine. If it's a label, and happens after the "END" statement, it is also a subroutine. Subroutines last until all paths return, but if the returns are nested inside of control statement you'll get a warning because it's hard to read. All of the pass1_* functions have to do with finding where subroutines start/end and adding them to the symbol table.

Pass 2 actually converts the parse tree to different structures representing statements, expressions, control flow blocks, etc (the abstract syntax tree - AST). Looking back, this is probably inefficient and could have been done in one pass, but it would be a lot of work to change that now. The classes that it uses are defined in ast.h.

Intermediate code generator (ast-gen-llvm.cpp)
This converts my structures to LLVM's. To understand this you'd probably have to read the LLVM docs. It's essentially a step above assembly language. LLVM then runs all kinds of optimizations on this and emits machine code. LLVM is used by Apple in Xcode, so if this was completed, you'd get an IBasic with industrial level optimizations.

About the language
I wanted to implement something as close to the original IBasic as I could. The differences between IBasic standard and pro show how the original language is not really suited well for compiling, but it's far from impossible. There are some syntax extensions I added:
- C pointer syntax. IBasic pointers are weird and kind of untyped but kind of not. I planned to support them eventually, but in the meantime, it was a lot easier to work with regular C pointers. Also, implementing the string type takes some work, so you have to use char* for now.
- STRING SETID. Has to do with the control statement, where you put the styles inside a string and they need to be expanded. Looking back there are probably better solutions to this, but I do need a non-const version for things like @code and @lparam and such in window handlers.
- Else if. Because why not?
- Commands and function pointers. If you write DECLARE "+", subname, it acts like $command did in IBasic Pro. Some different rules for not needing parenthesis. If you write DECLARE "#", name, you'll create a function pointer type. These two are needed to implement the standard libraries.
- Casting. Implicit conversions are mostly broken, and explicit probably is too in a lot of cases, but you can write "to <type>(expression)" to cast.
- USECOMPONENT was going to be the equivalent of the "add component" menu item in the IBasic IDE.
- ... for variable arguments functions. I also have a feature where it can automatically pass the length of the arguments list or a null after everything.
- A couple other operators like +=, ++, & (address of), _ (line extension), "" inside a string to produce a single quote (no more chr$(34)), and /**/ block comments.
- Most of these are necessary to write the standard libraries in GB itself. I didn't want to make a new language. IBasic was my first programming language, and I wanted to keep any changes I made minimal and in the same spirit, if that makes sense, but also make it a fast and fully featured development environment.

GWS

Ah! .. so parkovski = Parker ..  ;D

Now it makes sense  :) .. nice to see you back. It's been a few years I think.

Great to have a person with your skills on the forum again - not that I shall understand much of it ..  ;D ;D

Best wishes, :)

Graham
Tomorrow may be too late ..

Parker

Glad you remember me :). I think my last post was in '07 or so, but I've been checking in every few months to see how things are going.

When I brought up this idea last, it didn't seem very popular because it could take away from IBasic/CBasic sales. I'm a big fan of open source, but even if this language does become viable, I don't plan on doing any IDEs or whatever, so all the tooling and libraries could be community supported.

In high school some friends and I used to joke around with Russian accents. Parkovski was my Russian name :).

GWS

Parker,

Of course I remember ..  :) .. just look at the number of posts you made ..  ;D

Here's a thought though .. vis-à-vis me not understanding 'C'-like stuff .. ::)

Since CBasic is a sort of subset of EBasic (now IWB) .. would it be possible to implement the compiler for CB code using IWB instead of C ?

That would give more people a chance of understanding how it worked ..

All the best, :)

Graham
Tomorrow may be too late ..

aurelCB

April 17, 2013, 04:13:28 AM #13 Last Edit: September 21, 2016, 02:40:11 AM by aurelCB
thanks Parker on explanation... :o
This all looks like nightmare for coder not used to C/C++ programming
and i don't get it what kind of role LLVM doing here.
And why u use LLVM anyway, it looks to me that LLVM just complicate thing like low level virtual machine
acting as asembly transformator.
Sorry but i dont have VC2012 and don't have in plan to download this big package
+ LLVM as cource then compile this ,compile that and what a heck do Python here >:(.
I see that on LLVM page is pack for mingW32 and looks to me like simplier slution then VC pack.
Heh yes like GWS says it shouldbe easier to do this in EB/IWB but i think that this is not possible...
If i really catch some free time i will try to do somethig...

By the way do we have somewhere compiled testing exe of all this work ?

Rock Ridge Farm (Larry)

Long time back I told Graham I would look into a compiler for Cbasic - work and life keeps getting in the way.
I downloaded your code and hope to look at it soon.
Plan on finally retiring next year (Apr - Aug timeframe) so they are working me hard to complete all the open projects they have no one else to do. I have been telling my mgt. that they need to find my replacement for
2 years - they say OK then give me another crap project to finish - have about 3 on my plate at this time.
I am too old for this crap.

Anyway - thanks for the effort Parker - missed your input.

Larry


Parker

Graham - it would definitely be possible. I actually started that kind of project several times before I really understood compilers well. If I were going to go that route, I might even want to write it in CB so it would be able to compile itself later on. Probably the main reason why I did it in C++ is that I just heard about LLVM and wanted to try it out on something. I also had a mac at the time and couldn't run CBasic/IWBasic/etc, which was also part of my motivation for doing this.

Aurel - You're right. It's pretty ridiculous. I generally never try to build other people's C/C++ projects, because you're always missing some dependency or header file, or you didn't configure things right, or whatever. LLVM uses Python to build itself. All I know is if you don't have Python and you try to compile it, it will fail.

The advantages of using LLVM are basically that it is a lot simpler than assembly, way easier to write/understand, can output code for any architecture (I haven't tested it, but I should be able to select 64 bit in Visual Studio and magically get a 64 bit GlazBasic too), and comes with tons of optimizations that would be way too hard and time consuming to write myself. It's also incredibly well designed and helped me understand compilers a lot.

Larry - my code is not too well thought out to be honest. It works, and it's not terrible, but there are a lot of things I could have done better. You're welcome to do whatever you want with it though.

I have been wondering for a while if I should share this, and this thread gave me a good opportunity for that. I might add a couple more features, but these are really my last couple weeks of having a lot of extra free time, so I can't do much. If somebody wants to reimplement this though, I'm all for it, and I'll do my best to answer questions.

I'll upload an exe of this with a little demo game I made in a couple days - it's on my old laptop at my parents' house.

aurelCB

QuoteI'll upload an exe of this with a little demo game I made in a couple days - it's on my old laptop at my parents' house.

Thanks Parker...
then we can see what is this all about.
I know that author of o2 compiler tell on his forum about LLVM as a complete nightmare and
so much complicate some simple things that is to tuff to use than ordinary way.
And then this Python crap,oh boy for what kind of things someone need python to build intermediate
virtual machine ::)
With some good thinking few people can create compiled version of CBasic ,but must be few people
because this is not work for one enthusiast .

Steven Picard

April 18, 2013, 02:36:53 PM #17 Last Edit: April 18, 2013, 02:38:26 PM by Steven Picard
Hey, Parker, it's been ages but good to see you back!  :)

What are you up to these days? New hobbies? Still programming?

Parker

Hey Steven,

I am still programming - in fact, in about a month I leave to go start my 3rd programming internship. So it's looking like that will be my career, but I'm still trying to figure out exactly what I want to work on.

Aside from that, I am going to be in a musical written by a high school friend of mine (if anybody happens to be in Tucson - http://foxtucsontheatre.ticketforce.com/eventperformances.asp?evt=492).

I'm really not sure what I'm going to do in the fall though, but I suppose that's life. I've just gotta say though, it's really cool that you guys remember me after being gone for several years :). I'm really grateful for all the help I got from this community back when I was learning to program.

Parker

Ok. Here's the exe with a couple of test programs you can try: https://skydrive.live.com/redir?resid=A2353210AEF9D9D3!350&authkey=!ACI8PCV_5HGChj4
- textgame.gb is a (very) simple text based adventure game. Commands are "north/south/east/west, look, take <item>, use <item>, inventory, help, quit"
- cmdline.gb prints out all the command line arguments passed to it.

A few notes:
- This uses the LLVM JIT, so it won't actually produce exe files. It does however compile native code and run optimizations on it - you're welcome to try benchmarks or whatever.
- The compiler itself is kind of big and slow because it's a debug build. A release would be a lot smaller and quicker.
- You may need the VC++ 2012 runtime if you don't have it - you can probably find it on google.
- The biggest problem you'll run into if you try to write programs with this is that the string type is missing. It's hard to implement well though, so it'll probably stay that way for a while. Types also don't work, but a lot of the work for them is done and would be easy to finish.
- The print statement works, but only if you define the _GB_print* functions yourself (like in cmdline.gb).
- If you pass the "-ll" argument, you'll see the LLVM intermediate code produced for your program after all the optimization passes.

To run a program: open a command prompt window where your glazc.exe binary is, and type "glazc <source-filename>".