Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / [DBP] Simple BASIC Language made in DBPro

Author
Message
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 24th Aug 2008 06:12 Edited at: 5th Sep 2008 16:21
Hey all,

I haven't used DBP for a while, but today I just kinda felt like it, so I decided to revisit my old scripting systems and see if I could make anything better in DBP this time.


Update: slightly fixed version


Just make a file called "test script.txt" and put in this code:



Tell me if you find any problems,

Thanks.

The Heavy
15
Years of Service
User Offline
Joined: 6th Aug 2008
Location:
Posted: 25th Aug 2008 20:07 Edited at: 25th Aug 2008 20:09
Very nice, it has it's own built in expression parser and everything, I might try and expand on this with things like sub routines and maybe functions but they would probably require their own stacks, I'm not sure.

Edit: There's no support for indentation using tabs

Who touched my gun?
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 25th Aug 2008 20:13 Edited at: 28th Aug 2008 04:29
Functions aren't really that hard. When you compile a function declaration you add opcodes that pop the data stack into the parameter variables. When you call a function, you push the call location onto a function stack, and then jump to the function. When you return from a function, you check the top of the function stack and jump back to the call location, and pop it off the stack.

calcyman
16
Years of Service
User Offline
Joined: 31st Aug 2007
Location: The Uncertainty Principle
Posted: 27th Aug 2008 09:03
@Zotoaster:

I'm impressed with your expression parser, being able to handle both arithmetic (+,-,*,/), bitwise (&&, ||, !) and even comparative (<,>,=) operations.

However, it lacks boolean operators (AND, OR, NOT) that only work on one bit instead of the entire 32-bit integer.

For subroutines, the standard approach is to have a list (one-dimensional array) that contains the position where the program gosubbed from. Each time the program gosubs, an extra variable is stored in the stack and the stack pointer incremented. Each time the program returns, the last value is read off, and the stack pointer decremented.

I'm really impressed to find such a complex program at the top of the code snippets. It might have been more useful for you to have posted the internal sections seperately, possibly as functions. For example, I know that you could make a function like this:

function ParseExpression(expression as string)
result as float

...

endfunction result

which could be part of a scientific calculator program.

The optomist's right, The pessimist's right.
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 27th Aug 2008 15:55 Edited at: 28th Aug 2008 04:30
Calcyman,

Thanks very much for the compliments.

Actually, && and || also work as boolean. I use them like that in DBP all the time Can't remember the last time I used AND and OR. I haven't implemented NOT/! yet though, however, I do have a != operator.

The problem with the operators is that they don't have any precedence, so no BODMAS - you need to use brackets quite sparringly.

You are correct about subroutines too. The good thing about DBP is that it has resizable arrays (I have a feeling they used C++'s std::vector template class for that), so it's easy enough to implement a stack. [Anyone wanting to know the stack/queue commands should look in the Core Commands help section]

As for posting the sections seperately, well, it's all in functions anyway, lol. You tear it apart there as you wish. But your example wouldn't work in this anyway, because there are 4 main sections that are almost completely seperate from each other. All they do is pass on the result from each section to the next, i.e. Script Handler gets and formats the script, and passes it to the Tokenizer, which parses the script into little 'words' ('lexemes' or 'tokens' as they're called). The tokens get passed onto the compiler, which uses them to translate into a basic assembly-like language (if you change the bExecute variable at the top to 0 you can see the result of this), and that code goes onto the virtual machine, which executes it. Simply having a function to parse an expression and give you a result wouldn't fit anywhere, and besides, how would it know what variables are involved and what their value was anyway? I mean it could check realtime, but imagine how slow it would be to tokenize, compile and run a string realtime, heheh.

If you want to know more about expression parsing, look into 'The Shunting Yard Algorithm', which turns an infix expression (i.e. 3+4) into postfix notation (i.e. 3 4 + ), and then 'Reverse Polish Notation', which solves postfix equations. It's really easy, and both algorithms are on wikipedia.

Anyway thanks again, and sorry for the long post. I'm glad to see you scrutinized my code so carefully

BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 1st Sep 2008 17:32


calcyman
16
Years of Service
User Offline
Joined: 31st Aug 2007
Location: The Uncertainty Principle
Posted: 5th Sep 2008 12:27
When I executed it, I got the standard "array does not exist or array subscript out of bounds" in your ScGetToken() function. I generally use long fixed-length 1-dimensional arrays rather than expandable stacks, as they seem safer.

In your ScTokenise function, have you considered using the SELECT, CASE, ENDCASE, ENDSELECT commands? I would imagine that they are faster than using lots of conditional if statements.

Does your program ignore empty space? Here's a function that removes empty space from a string, which I've converted into your structured format:



As for string concatenation, the easiest way to do that is to get your conditional-if statement, replace "then" with a carriage return, to replace a colon with a carriage return, and to place "endif" on the next line.

It shouldn't be too hard to implement this at the start of your code:



No prizes for guessing what it does!

The optomist's right, The pessimist's right.
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 5th Sep 2008 16:19
I just tried recompiling that code and I got the same error. I suppose I must have made a mistake while editing the post or something. I've updated the top post with a newer version I made a few days ago. This includes reading scripts from files, and ignoring tab spaces, which unlike before, only removes normal spaces (the function that does this is scRemoveWhite() in the general functions section, line 1593).

The string concatenation problem happens when trying to + two strings together. I suppose I can try and fix that up next time (none of the operators currently support strings), as well as make some basic subroutines and then updating them to become functions (with parameters and return values).

Cheers

HeavyAmp
17
Years of Service
User Offline
Joined: 25th Oct 2006
Location: Castle in the Sky!
Posted: 6th Sep 2008 02:29
Nice work Zotoaster getting featured in the Newsletter. Most your code goes over my head. To many bit operators for me

Better to be dead, than to live your life afraid.
ozmoz
16
Years of Service
User Offline
Joined: 25th Apr 2007
Location:
Posted: 21st Sep 2008 05:19
very coll work
i like it
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 21st Sep 2008 20:07
Thanks ozmoz.


HeavyAmp,

Quote: "To many bit operators for me"


Well as I stated earlier, the bit operators can be used as boolean operators too. I'm just in the habit of doing that, lol. && = AND, || = OR. Easy as pi.

Login to post a reply

Server time is: 2024-04-16 18:35:23
Your offset time is: 2024-04-16 18:35:23