PCOPY! Issue #70 ~ June 3rd 2008
From Our Editing Desk (Da Editors)
Submitting to PCOPY! (MystikShadows & E.K.Virtanen)
Letters To The Editors (Mixed Contributors)
In The News (Mixed Contributors)
Exit Issue (MystikShadows)
Extreme Programming Evaluation And Review (MystikShadows)
Interview With Roy Scott (E.K.Virtanen)
Interview With Galleon (E.K.Virtanen)
Tutorials & HowTo's:
The DEF of the XBLite Programmer (Guy "gl" Lonne)
Programming Simulations - Part 2 Real World Example (MystikShadows)
Marrying YaBasic And Ubuntu (E.K.Virtanen)
Guy (gl) Lonné
Date May 26th 2008
~ REGULAR COLUMNS ~
From the Editors: by Da Editors
Hello to one and all, here it is, at long last, Issue #70 fresh off the press!
Yes indeed, we're well aware of how long it's been since the last release of PCOPY! There was more than one reason for this delay. The first was contents both things we wrote and things contributed by others. We're thinking that spring isn't one of the best seasons for contributions. The other one, was a possible new template and style for this magazine (more on that later). But at long last, it's here.
In this issue E.K. really got busy and prepared us two interviews one from Roy Scott (who seems to be renowned all over the BASIC web, pretty much) and another from Galleon (who is getting renowned as we speak with his QB64 project). E.K. also managed to create a how to article about running YaBasic on Linux. Guy Lonné has his second instalment about the ABCs of XBLite (entitled DEF of XBLite, very fitting title hehe). I start my second part in Simulation series.
As a special note I'd like to thank Petr Schreiber for his efforts in correcting some of the submissions for spelling and other errors. Great work if I do say so myself.
Feel free to sit down at your favourite computer chair (yeah the one you're probably sitting on right now hehe) and let the reading begin!
PCOPY! Editors & Contributors
Submitting to PCOPY!: by Stephane Richard & E.K.Virtanen
As you probably noticed, we have a list of contributors. Everyone that submits something gets his/her name added to this list for the particular issue the submission appears in. We can't claim to know every single BASIC dialect out there nor can we claim to know how to program in all of them. There are just too many of them. Hence, this is an official invitation to those of you that do know a specific BASIC dialect well enough to write about it. Help us make PCOPY!, the most complete BASIC magazine there can possibly be by sending us submissions about them.
When we say submissions we mean anything that pertains to the specific BASIC dialect in question. Submissions can range from simple news item (a new version comes up, a new library is available and the likes), they can be personal reviews of a given BASIC interpreter/compiler, they can be tutorials, tips and tricks that shows readers how to accomplish a given task in the BASIC of your choice. The choice is yours. Submissions will help make PCOPY! even better than it is and the end result of that is that readers will have better BASIC related material to read in every issue that comes up.
So don't be shy, you know something others don't about a given BASIC, let us know about it, send us your submissions and we'll take it from there. If you're not sure how good writer you are don't worry, if needed, we'll edit and format the submission accordingly. So please, submit whatever you have time to write.
All submissions can be sent to email@example.com and will typically be added in the issue that is currently being worked on at the time the submission is sent to us.
Letters To The Editors: By Mixed Contributors
Letter from E.K.Virtanen
Short Statement From The Editor Of The Last Issue.
Hello Mr. Virtanen.
In The News:(Mixed Contributors)
sdlBasic 2'nd April 2008: Alcor 0.7 is out. Alcor is the next step of sdlBasic development this is a snapshot of the current preliminary and unstable version.
ASCII-World suffers for a bad karma. Currently all files hosted there are offline and hosting company seems unreachable. E.K.Virtanen is still trying but is ready to soon move everything to different hosting company.
SmallBasic and specially Palm version of it seems to worry some users at http://smallbasic.sourceforge.net forums.
thinBasic is about passion what we can see easily when we look at the released updates. thinBasic version 220.127.116.11 released at 2008.05.15
QBExpress #28 was released at 11'th May 2008. As commonly known, QBE has many interesting contents and it is worth of checking even if you don't use QB/FB. See more at petesqbsite.com
Brutus2D V1.8.3 released May 7, 2008.
22-Mar-2008 was the date when Basic4GL Version 2.5.3 released.
FreeBasic 0.18.5b released at April 18th, 2008
John Spikowski posted about ScriptBasic 2.2 Release Goals at Apr 26'th, 2008
AutoIt(freeware BASIC-like scripting language) v18.104.22.168 released 16'th May, 2008
FREE Basic Script Language v4 topic started at May 13, 2008.
Ocean Basic project is back online! Bit old news since site has been up since January 20'th, but better late than never.
Extreme Programming Evaluation And Review: by MystikShadows
If you're in the field of software development and/or software engineering you've probably heard, one way or another, about Extreme Programming. Extreme Programming can be considered more of a work ethic than an actual Programming paradigm in that it instates many control process in every day programming tasks.
Extreme Programming is one of the newer software engineering methods (Founded in 2001) developed by Kent Beck (One of the original 17 signatories in the Agile Manifesto). Its track record, after eight years of usage scenarios, is actually quite successful. Many companies attribute to the XP Principles which are geared towards customer satisfaction and rapid response to change.
WHAT EXTREME PROGRAMMING IS:
Extreme Programming is a software engineering discipline that is designed, from the grounds up, to allow flexibility in design, programming and testing in such a way that it can respond quickly to the changing requirements of customers. This can even happen late in the life cycle of a software development project and doesn't promote the creation of the classic notion that is patch development.
At the same time, Extreme Programming follows the principle that two heads are often better than one in that paired programming is highly encouraged in software development efforts. It has roles for users, designers, developers that allow them to work closely with each other which help in the way the methodology responds to changes in a design and in the resulting application.
THE RULES OF EXTREME PROGRAMMING:
Extreme Programming is entirely governed by a set of preset rules which when used together is designed to optimize the time spend on every aspect of software development. The rules are broken down into four phases as follows:
As you can see here this rather short list of rules (compared to some other methodology) is actually surprisingly simple. Likewise, the relationship between each step in each part of the development phase as well as the relationship between each of the phases themselves all contribute to providing a fast changing working environment that can easily, when all elements are present, adapt to any new situation, change, additions because everything and everyone as so closely related to the outcome of the software development process.
Based on experience and projects that were created using Extreme Programming, projects that are object oriented in nature are typically better managed because the object often represent a great complete functional iteration that is self sufficient and easy to create test units for as independent iterations. However, modular projects when organized accordingly can play the same role so Extreme Programming is good for all kinds of projects.
EXTREME PROGRAMMING RUMOR EXPLORATION:
Extreme programming is roughly about 8 years old (at the time of this writing) and although computers and computer programming are usually rapidly changing to adapt to new reality of the hardware and the increasing needs of the users, in the software engineering world, 8 years makes extreme programming rather new compared to other methodologies. As such, Extreme Programming has accumulated rumours along the way as it tries to make its way into the software engineering methodologies. In the last revision of the SWEBOK (The SoftWare Engineering Body Of Knowledge) Extreme Programming was not added to the body of knowledge. Perhaps it will make it into the next revision as it continues to be used successfully in more and more types of projects.
Let's take a look at some of the more widespread rumours about Extreme Programming that might explain why it was not voted in the SWEBOK reference:
These are the two major rumours. There are more of course, Also, many existing rumours were created because Extreme Programming was not known or used. Hence, people didn't understand what it was all about. Extreme Programming has failed in some projects. However, the story doesn't say that extreme programming itself failed or if the group of developers that tried to use it failed at using it the right way (since some of the notions of extreme programming are very different from the conventional programming practices it's quite possible that some of it was too different and therefore the people trying to use it couldn't part themselves that far away from the ways of software engineering they already knew). After 8 years of existence, I'd be curious to see how Extreme Programming would do if it was to be used on the exact projects where they were deemed a failure especially now that extreme programming rules and principles are probably more understood than it was when these projects failed.
The best advice I can give you is to use the reference links I provided below and read about Extreme Programming. See what you can make of it, create your own conclusions and make your own opinion about it. As far as I'm concerned I like what Extreme Programming is all about. Not just because it's a brand new methodology (a new methodology is probably long overdue in the software engineering field) but because of the way that even if a rather big group of people are involved in a given project, Extreme Programming really seems to allow to shift the project around, remove or change existing functionality with minimal impact on other existing functionality since testing is performed before, during and after each of these changes.
All in all, Extreme Programming is proving itself successful on big projects. Since these big projects are the projects that represent the biggest time and money investments it's only natural that this be the first place where the rate of success can be quantitatively measured and seen. If you have 2 or more people (an even number of programmers works best for pair programming) any project, whether commercial or personal should benefit from the same advantages that the bigger projects have seen. In fact, in a smaller group of developer it is probably easier to maintain a tight control over the development of rugged test units and functional code for a given project. But don't take my word for it, take a look around, read and learn about Extreme Programming, find it where it's been successful, where it failed and why. And then decided of extreme programming is for you.
Here are links of websites I've used throughout this evaluation document. You can find a whole lot of details, explanation and examples concerning the Agile Methodologies and more specifically about Extreme Programming.
Interview With Roy Scott: by E.K.Virtanen
Roy Scott probably doesn't need much of an introduction in the world of basic compilers and interpreters today. Sooner or later you've come across his website and/or posts on some forums somewhere at some point if you program in BASIC. He's most renowned for his Roy Scott Free Site. Bottom line, Roy Scott is a veteran micro developer that knows his way around many languages and many types of programming projects. Here is an interview I did with Roy to help you learn a bit more Roy Scott as a programmer and as an individual.
Q: Let's start with the "stats". Who, what and from where?
Interview With Galleon: by E.K.Virtanen
I'm not sure how many of you have heard of Rob (Galleon is his nickname). But you might know of some of his projects, the current project is called QB64 and aims to present programmers with a QB clone language that is capable of running in all modern Operating Systems (Such as Windows XP, Vista and Linux). This project can be followed in this sub forum on The QBasic Forum Community. Here I interviewed Galleon to present this individual to you and let him talk about himself. As the old saying goes, you can only get the truth about someone by asking that person the questions, which is what I did, right here.
Q: Let’s start with the "stats". Who, what and where?
The "D.E.F." of the XBLite Programmer: by Guy (gl) Lonné
This article is the sequel of the article "The ABC of the XBLite Programmer": the exposed concepts are pushed one step further. However, you need to read first the "ABC” article otherwise this "DEF” article will not make sense to you.
As seen previously, the division is the more complex arithmetic operator to put in use because of the divide-by-zero risk and also because it gives both a result and a remainder.
With what we already know, the remainder is computed as follows:
result = number / divider remainder = number - (result * divider)
However, if result can be discarded, the same can be achieved with the operator MOD:
remainder = number MOD divider
In my recent developments, I used MOD in these 2 cases:
Example 1: Make a running index wrap around
Stepping thru an array, I had to wrap around when exceeding the upper bound.
INC index IF index >= indexSup THEN index = 0 Then, I replaced it by: INC index index = index MOD (indexSup + 1) Gotcha: index off by 1
Since MOD returns a number between 0 and divider minus 1, you have to use index MOD (indexSup + 1), otherwise index will never reach indexSup but (indexSup - 1) (the "off-by-1" bug).
Example 2: Is yyyy a leap year?
A leap year has a 29 day March, when the others have only 28 days in March. In the Gregorian calendar, a leap year occurs generally every 4 years, skipping secular years.
Is leap a year, which is:
This is when MOD does a great job:
reminder = yyyy MOD 4 IF reminder THEN ' not a multiple of 4 bLeapYear = $$FALSE ' not leap ELSE reminder = yyyy MOD 100 IF reminder THEN ' not a multiple of 100 bLeapYear = $$TRUE ' leap ELSE ' multiple of 100 (secular year) reminder = yyyy MOD 400 IFZ reminder THEN ' multiple of 400 bLeapYear = $$TRUE ' leap ELSE bLeapYear = $$FALSE ' not leap END IF END IF END IF
Question: Was 2000 a leap year? (Answer: yes!)Gotcha: Never divide by zero (the old nasty bug) Always guard from dividing by zero. In doubt, test for a zero divider:
IFZ divider THEN ' error: division by zero ELSE remainder = number MOD divider END IF
Decisions: Short forms of IF
- IFZ <=> IF 0 == - IFF <=> IF $$FALSE ==, or IF NOT
My rules of thumb regarding Short Forms of IF
I always use IFZ, but never IFF: testing a zero value seems "natural" to me but not to test a false condition; if I have to, I use IF NOT instead of IFF since it stands out and yells "Warning, false condition!" in a code review when IFF barely draws attention.
Decisions: Complex conditions (&& and || operators)
To build a complex condition, combine the individual conditions with the logical operators: logical and (&&), logical or (||).
You can easily spot the logical operators because they are doubled: &&), ||, and even == (always shortened = in practice).
bLeapYear = $$FALSE ' not leap IFZ (yyyy MOD 4) THEN ' multiple of 4 IF (yyyy MOD 100) > 0 THEN bLeapYear = $$TRUE ' leap ELSE IF ((yyyy MOD 400) = 0) THEN bLeapYear = $$TRUE ' leap END IF END IF
Gotcha: Never use the bitwise operators to combine logical conditions
You have to use && and || in an IF (complex condition) THEN. AND is the bitwise and operator, OR is the bitwise or operator.
Idiom: Using addition instead of && for testing a resulting zero condition
bLeapYear = $$FALSE ' not leap IFZ (yyyy MOD 4) THEN ' multiple of 4 rem100 = yyyy MOD 100 IF rem100 THEN bLeapYear = $$TRUE ' leap IFZ rem100 + (yyyy MOD 400) THEN bLeapYear = $$TRUE ' leap END IF
Multiple Decisions: SELECT CASE TRUE
A series of IF's are better replaced by an equivalent SELECT CASE TRUE (for my taste). This statement is specific to XBLite and is incredibly handy to handle sequential conditions.
Example: Is yyyy a leap year? (final version)
SELECT CASE TRUE CASE yyyy MOD 4 ' not a multiple of 4 bLeapYear = $$FALSE ' not leap ' CASE yyyy MOD 100 ' not a multiple of 100 bLeapYear = $$TRUE ' leap ' CASE yyyy MOD 400 ' not a multiple of 400 bLeapYear = $$FALSE ' not leap ' CASE ELSE ' multiple of 400 bLeapYear = $$TRUE ' leap ' END SELECT
Gotcha: The conditions are sequentially tested
the conditions are applied one by one, from the first condition towards the last, until there is a TRUE condition:
XLONG myLongArray[upper bound] STRING myStringArray[upper bound]
Gotcha: DIM redeclares an array and resets its contentsAt run-time, DIM clears an array and redefines its upper bound:
DIM myArray[new upper bound]
If you want to preserve the array contents, use instead:
REDIM myArray[new upper bound]
Idiom: Test if an array is empty
IFZ myArray THEN ' array is empty!
This is the short for:
upp = UBOUND (myArray) IF upp < 0 THEN ' array is empty!
Gotcha: empty array
An empty array has an upper bound of -1.
Idiom: Testing if array myArray is empty
IFZ myArray THEN ' array myArray is empty! END IF
This is the short for:
upp = UBOUND (myArray) IF upp < 0 THEN ' array myArray is empty! END IF
XBLite's string handling is both complete and convenient. A string can be manipulated both as an array of characters and as zero-terminated for C's compatibility.
However, I never manipulate a string as a character array: XBLite offers a rich set of string functions and these functions will never cause a program crash.
Explicit String Declaration
STRING myString ' string STRING myStringArray[upper bound] ' array of strings
I always prefer to use implicitly declared strings (text$ = "some text"), but you must declare explicitly the arrays:
STRING dayOfWeek$ ' declares an array of day's names dayOfWeek$ = "Monday" dayOfWeek$ = "Sunday"
You might prefer the all run-time alternative:
DIM dayOfWeek$ ' array of day's names dayOfWeek$ = "Monday" dayOfWeek$ = "Sunday"
Let's do some string operations:
myString$ = "12345" ? "myString$ is "; myString$ prints "myString$ is 12345”
Note: ? is the short form of PRINT.
? "Length is"; LEN (myString$) prints "Length is 5"
- LEFT$ (myString$): first character of string myString$
? "First character is "; LEFT$ (myString$) prints "First character is 1"
- LEFT$ (myString$, cChar): cChar leading characters of string myString
cChar = 3 ? cChar; " leading characters are "; LEFT$ (myString$, cChar) prints " 3 leading characters are 123"
- RIGHT$ (myString$): last character of string myString$
? "Last character is "; RIGHT$ (myString$) prints "Last character is 5"
- RIGHT$ (myString$, cChar): cChar trailing characters of string myString$
cChar = 2 ? cChar; " trailing characters are "; RIGHT$ (myString$, cChar) prints " 2 trailing characters are 45"
- LCLIP$ (myString$): clips off the first character of string myString$
? " 4 remaining trailing characters are "; LCLIP$ (myString$) prints " 4 remaining trailing characters are 2345"
- LCLIP$ (myString$, cChar): clips off cChar leading characters of string myString$
cChar = 2 ? LEN (myString$) - cChar; " remaining trailing characters are "; LCLIP$ (myString$, cChar) prints " 3 remaining trailing characters are 345"
- RCLIP$ (myString$): clips off the last character of string myString$
? " 4 remaining leading characters are "; RCLIP$ (myString$) prints " 4 remaining leading characters are 1234"
- RCLIP$ (myString$, cChar): clips off cChar trailing characters of string myString$
cChar = 2 ? LEN (myString$) - cChar; " remaining leading characters are "; RCLIP$ (myString$, cChar) prints " 3 remaining leading characters are 123"
- subString$ = MID$ (myString$, pos): extracts a sub-string from myString$ starting from character at position pos.
pos = 2 ? LEN (myString$) - pos + 1; " remaining trailing characters are "; MID$ (myString$, pos) prints " 4 remaining trailing characters are 2345"
- subString$ = MID$ (myString$, pos, cChar): extracts cChar characters from myString$ starting from character at position pos
pos = 2 cChar = 3 ? cChar; " characters starting position"; pos; " are "; MID$ (myString$, pos, cChar) prints " 3 characters starting position 2 are 234"
- pos = INSTR (myString$, searchFor$): look for a sub-string in myString$ starting from the first character
searchFor$ = "45" pos = INSTR (myString$, searchFor$) ? "Sub-string "; searchFor$; " found starting position"; pos; " ==> "; MID$ (myString$, pos, LEN (searchFor$)) prints "Sub-string 45 found starting position 4 ==> 45" searchFor$ = "8" pos = INSTR (myString$, searchFor$) ? "Sub-string "; searchFor$; " not found (position ="; pos; ")" prints "Sub-string 8 not found (position = 0)"
- pos = INSTR (myString$, searchFor$, start): look for a sub-string in myString$ starting from the character at position start
searchFor$ = "45" pos = INSTR (myString$, searchFor$, 2) ? "Sub-string "; searchFor$; " found starting position"; pos; " ==> "; MID$ (myString$, pos, LEN (searchFor$)) prints "Sub-string 45 found starting position 4 ==> 45" start = pos + 1 pos = INSTR (myString$, searchFor$, start) ? "Sub-string "; searchFor$; " not found when searching from position"; start prints "Sub-string 45 not found when searching from position 5"
- prefix R (RINSTR): reverse search
pos = RINSTR (path$, ".") ' look for the file extension
- suffix I (INSTRI): search case insensitive
pos = RINSTRI (path$, ".bat") ' look for a batch
These functions are safe: you will never crash even if you go outside string's boundaries.
- lowCase$ = LCASE$ (myString$): changes all characters from myString$ to lowercase
myString$ = "WAS UPPERCASE" newString$ = LCASE$ (myString$) ? "original string: "; myString$; ", new string: "; newString$ prints "original string: WAS UPPERCASE, new string: was uppercase"
- uppCase$ = UCASE$ (myString$): changes all characters from myString$ to uppercase
myString$ = "was lowercase" newString$ = UCASE$ (myString$)? "original string: "; myString$; ", new string: "; newString$ prints "original string: was lowercase, new string: WAS LOWERCASE"
Idiom 1: test if a string is empty
IFZ myString$ THEN ' empty this is the short for: IFZ LEN (myString$) THEN ' empty
Idiom 2: scan a string
FOR pos = 1 TO LEN (myString$) SELECT CASE MID$ (myString$, pos, 1) CASE "1": ... CASE "2": ... END SELECT NEXT pos
Idiom 3: find a sub-string
IF INSTR (myString$, "sub-string") THEN ' found!
Idiom 4: check Yes/No answer, whatever is its case
IF INSTRI ("yes/no", resp$) THEN ' found!
(Note the slash to invalidate "sno" or similar invalid strings)
SELECT CASE LCASE$ (resp$) CASE "yes", "no" ' found! END SELECT
Putting your new knowledge in action
As a brain teaser, here is one that I invented in 1978, after reading a science fiction book. In the SciFi book, it was called "The KAPREKAR Algorithm", and it was supposed to produce a "mathematical pit".
A year later, I spoke to the youngest of my four sisters (she is the brainy One in the family). She told me that she read about it in an article from François LE LYONNAIS, an inventive French Mathematician and a very good chess commentator. Well, it shows that while my sister was reading math articles, I was read SciFi books…
At the time, I coded this algorithm in FORTRAN as a final project for my first year of my computer degree and my sister told me that the teachers used this very algorithm for the final exam of a later promotion.
Here is the challenge: Hello Mr KAPREKAR!
A math pit is a non-zero 4 digit number, which remains unchanged after the following manipulation:
Iterate until all digits are equal
It took me 3 hours to code the KAPREKAR algorithm in XBLite. The answer is a single mathematical pit: 6174 found after at most 8 iterations.
What about trying this challenge?
Here is my solution. I welcome all comments on it.
PROGRAM "kaprecar" VERSION "1.00b" CONSOLE ' kaprecar - KAPREKAR Algorithm ' GPL 2007 Guy "gl" Lonne, dedicated to my dear sister Francoise ' Source code released under GNU GPL ' ' ***** Description ***** ' kaprecar is an implementation of the KAPREKAR Algorithm, which produces ' a "mathematical pit". ' ' A math pit is a non-zero 4 digit number, which remains unchanged after ' the following manipulation: ' Iterate until all digits are equal ' 1. Sort the 4 digits as (a, b, c, d), a <= b <= c <= d (a being the ' smallest) ' 2. Make a new 4 digit number: dcba ' 3. Make a new 4 digit number: abcd ' 4. Compute the difference: dcba - abcd: this difference is a math pit ' candidate ' 5. Test if the difference is the same number as the previous iteration ' 6. Extract from the difference the 4 digits (a, b, c, d) ' ' There is a single mathematical pit: 6174 found after at most 8 iterations. ' ' ***** Versions ***** ' gl-05mar07-v1.00a: creation. ' gl-05mar07-v1.00b: optimized. ' DECLARE FUNCTION Entry () FUNCTION Entry () ' mathPit[i1000, i100, i10, i1] is a 4-dimensional array DIM mathPit DIM acIterMax cPit = 0 cTries = 0 FOR i1000 = 0 TO 9 FOR i100 = i1000 TO 9 FOR i10 = i100 TO 9 FOR i1 = i10 TO 9 ' seed = (i1000 * 1000) + (i100 * 100) + (i10 * 10) + i1 SELECT CASE seed CASE 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999 CASE ELSE ' ' -PRINT "processing"; seed INC cTries d = i1000 c = i100 b = i10 a = i1 n4digits_old = 0 cIter = 0 bMathPit = $$FALSE DO INC cIter ' ' sort the digits ascending as (a, b, c, d), ' a <= b <= c <= d (a being the smallest) DO ' bSwap = $$FALSE SELECT CASE ALL TRUE CASE a > b : SWAP a, b : bSwap = $$TRUE CASE b > c : SWAP b, c : bSwap = $$TRUE CASE c > d : SWAP c, d : bSwap = $$TRUE END SELECT ' LOOP UNTIL !bSwap ' dcba = (d * 1000) + (c * 100) + (b * 10) + a abcd = (a * 1000) + (b * 100) + (c * 10) + d ' -PRINT "sorted descending "; dcba ' -PRINT "sorted ascending "; abcd ' n4digits = dcba - abcd IFZ n4digits THEN EXIT DO ' 0000 is not a math pit IF n4digits = n4digits_old THEN bMathPit = $$TRUE ' -PRINT "it's a math pit "; n4digits EXIT DO ' it's a math pit! END IF ' n4digits_old = n4digits ' save current value ' ' extract the digits d = INT (n4digits / 1000) remind = n4digits - (1000 * d) ' c = INT (remind / 100) remind = remind - (100 * c) ' b = INT (remind / 10) a = remind - (10 * b) ' LOOP ' IF bMathPit THEN SELECT CASE TRUE CASE cIter <= 2 ' print the minimum s$ = STRING$ (seed) SELECT CASE LEN (s$) CASE 1 : s$ = "000" + s$ CASE 2 : s$ = "00" + s$ CASE 3 : s$ = "0" + s$ END SELECT ' ? "Math pit:"; n4digits; ", found after only"; _ cIter; " iterations processing "; s$ END SELECT ' IFZ cPit THEN ' 1st math pit mathPit = n4digits acIterMax = cIter cPit = 1 ' count the math pit ELSE found = - 1 upp = cPit - 1 FOR z = 0 TO upp IF mathPit[z] = n4digits THEN found = z ' math pit already recorded EXIT FOR END IF NEXT z ' IF found > - 1 THEN ' math pit already recorded IF acIterMax[found] < cIter THEN acIterMax[found] = cIter END IF ELSE INC upp ' REDIM mathPit[upp] mathPit[upp] = n4digits ' REDIM acIterMax[upp] acIterMax[upp] = cIter ' INC cPit ' count the math pit END IF ' not known ' END IF ' 1st time END IF ' math pit END SELECT ' NEXT i1 NEXT i10 NEXT i100 NEXT i1000 PRINT "\n\nKAPREKAR Algorithm tried on"; cTries; " 4-digit numbers." ' 495 4-digit numbers IFZ cPit THEN PRINT "I did not find any mathematical pit." ELSE upp = cPit - 1 FOR i = 0 TO upp PRINT "Math pit:"; mathPit[i]; ", found after at most", acIterMax[i]; " iterations" NEXT i END IF a$ = INLINE$ ("\nPress Enter to quit >") END FUNCTION END PROGRAM
Useless as it seems, the kaprekar algorithm has been used for computer generated graphical patterns; see some applications of the Kaprekar algorithm at http://mathworld.wolfram.com/KaprekarRoutine.html
Overview of variable definition
I use and abuse of the implicit types (XLONG and STRING), but sometimes, the implicit types will not do. Time has come to try other data types.
In XBLite, data representation comes in many sizes and shapes, for very good reasons:
In case you have to, here is your road-map for this jungle:
Built-In Data Types sfx Description Bit Size Data Type =================== === ================== ======== ============= SBYTE @ signed byte 8-bit integer UBYTE @@ unsigned byte 8-bit integer SSHORT % signed short 16-bit integer USHORT %% unsigned short 16-bit integer SLONG & signed long 32-bit integer ULONG && unsigned long 32-bit integer XLONG register type 32-bit integer GOADDR address type 32-bit integer SUBADDR address type 32-bit integer FUNCADDR address type 32-bit integer GIANT $$ signed giant 64-bit integer SINGLE ! single float 32-bit IEEE Single Precision Floating Point DOUBLE # double float 64-bit IEEE Double Precision Floating Point LONGDOUBLE ## long double float 96-bit IEEE Long Double Precision Precision Floating Point STRING $ ubyte string 8-bit unsigned bytes (characters) SCOMPLEX single complex 32-bit floating point DCOMPLEX double complex 64-bit floating point Examples ======== int8s@ = 1@ SBYTE int8u@@ = 1@@ UBYTE int16s% = 1% SSHORT int16u%% = 1%% USHORT int32s& = 1& SLONG int32u&& = 1&& ULONG int32s = 1 XLONG int64s$$ = 1$$ GIANT sgl32s! = 1! SINGLE dbl32s# = 1.0# DOUBLE dbl64s## = 1.0## LONGDOUBLE char@@ = 'A' UBYTE str$= "ABC" STRING
Composite type (also called User Data Type)
A composite type is a combination of XBLite built-in types. It is declared:
TYPE MY_TYPE XLONG .myLong XLONG .myLongArray[upper bound] STRING * maximumLength .myString STRING * maximumLength .myStringArray[upper bound] END TYPE
Note that all XBLite types are explicit and all strings have a fixed size.
I like to use composite types: they are a great way to package together related variables. For example, SHARED variables, or interface parameters, or "object" attributes.
Declaration of a composite type
A composite type is first declared as:
TYPE myType XLONG .myLong STRING * 255 .myString END TYPE
(note the dot preceding the name)
Definition of a UDT variable
The data type being declared, the variable can be defined with it:<>/p>
Using a UDT variable
You can access the individual items:
myUDT.myLong = 2 IF INSTR (myUDT.myString, "text") THEN
The UDT variables come with their own problems:
length = LEN (CSIZE$ (myUDT.myString))
Gotcha 1: string are defined with a fixed size
Composite strings have an explicit size, which is never zero (empty string): an empty string is in fact padded with binary zeroes (null characters).
IFZ myUDT.myString THEN
does not work.
IFZ CSIZE$ (myUDT.myString) THEN
CSIZE$ is a function that looks for the first null character and clips string off at this null character. The zero byte is represented by \0 or '0'.
Gotcha 2: numeric fields are padded up to the byte
For example, a USHORT is padded to the size of XLONG.
To illustrate a consequence of this difference, here is a small demo program in which I move -1 in an unsigned byte (horror!). If the UBYTE belongs to a structure, XBLite converts -1 to 255. If not, -1 is left unchanged.
VERSION "1.00" CONSOLE ' ' Outputs of this program ' ======================= ' 'Case 1: IF winBack.color_coef = -1 THEN with_1 = -1 ELSE with_1 = 5 ' coef = winBack.color_coef ' ' winBack.color_coef = 255, coef = 255, with_1 = 5 ' '==> problem 1 occurred: coef <> with_1 255 <> 5 ' 'Case 2: IF ubyte@@ = -1 THEN with_1 = -1 ELSE with_1 = 5 ' coef = ubyte@@ ' ' ubyte@@ = -1, coef = -1, with_1 = -1 ' 'Press Enter to quit > ' IMPORT "xst" ' XBLite Standard Library TYPE WIN_BACK UBYTE .color_coef END TYPE DECLARE FUNCTION Entry () ' program entry point FUNCTION Entry () XLONG bAdd WIN_BACK winBack bAdd = $$FALSE winBack.color_coef = - 1 ubyte@@ = - 1 ' implicitly UBYTE ? "Case 1: IF winBack.color_coef = -1 THEN with_1 = -1" ? " ELSE with_1 = 5" ? " coef = winBack.color_coef" ? ?, "winBack.color_coef = "; winBack.color_coef; ' --------------------------------------------------works IF winBack.color_coef = - 1 THEN with_1 = - 1 ELSE with_1 = 5 END IF ' -----------------------------------------does not work coef = winBack.color_coef ' ----------------------------------------------------------- ? ", coef = "; coef; ", with_1 = "; with_1 IF coef <> with_1 THEN ? "\n==> problem 1 occurred: coef <> with_1"; coef; " <> "; with_1 END IF ' =========================================================== ? ? "Case 2: IF ubyte@@ = -1 THEN with_1 = -1 ELSE with_1 = 5" ? " coef = ubyte@@" ? ?, "ubyte@@ = "; ubyte@@; ' --------------------------------------------------works IF ubyte@@ = - 1 THEN with_1 = - 1 ELSE with_1 = 5 END IF ' -----------------------------------------does not work coef = ubyte@@ ' ----------------------------------------------------------- ? ", coef = "; coef; ", with_1 = "; with_1 IF coef <> with_1 THEN ? "\n==> problem 2 occurred: coef <> with_1"; coef; " <> "; with_1 END IF ? a$ = INLINE$ ("Press Enter to quit >") QUIT (0) END FUNCTION END PROGRAM
Yes! Composite types are useful!
I did not mention this to prevent you from using composite types as they are very convenient in a lot of situations. However, remember that the composite items don't quite map their built-in counterparts.
At this point, it is up to you to become very proficient with XBLite. But remember, only practice makes perfect, regular practice.
I suggest that you write a series of small console programs: the ever classic guess game is a must, actually, all the good old BASIC games are perfect to acquire skills, which are knowledge in action. So, download the latest distribution of XBLite (release 2.40 still cooling from baking), and grind your teeth on:Kindly Rat's GWBASIC website
The Old Gem - Basic
to name a few.
Well, this could be a hobby of yours for, at least, the next two years...
Guy "gl" Lonné
As David announced 15 April 2008 in the XBLite Google Group:
Programming Simulations - Part 2 Real World Example: by MystikShadows
Welcome to this second part of my simulation series. If you remember, in The First Part, we covered a lot of theory about what a simulation (or simulation game) is as well as what the elements of a simulation are and possible ways they could or would need to interact with each other. Although the ultimate goal of this series is simulation games, the theory can typically best be applied (and learned) much better when used in a real world situation. The reason is the reader can relate to that real world situation in terms of understanding the different parts much better than in a game where first the user needs to situate himself/herself in the game first then comes figuring out what part does what. Don't worry though, we'll be making a simulation game in the next part of the series.
Hence, in this second part of the series, we'll put the knowledge we learned to use in an actual real world situation that we often hear of. We'll go through the steps of defining the components of the simulation and see if and how they need to interact with what other system in order to perform their designated functions. Once we define all the parts of this simulation in this article and in the next article we will detail and explain the code itself. This way you will have time to digest the information here (as it is a big article in itself). It will also give you some time to ask me questions should you have any about certain aspects of this project. So let's get right to it shall we?
THE REAL WORLD SITUATION:
Here's the situation, you won the lottery (very real world situation no?) and you decide to buy yourself a dream house. You find the perfect house for your taste (almost as of you designed it yourself) it's a rather new house built 2 years ago, it has a great big backyard with a pool, really, everything you want in a house. The only inconvenience is it's in a part of town where robbery and other crimes seem to occur a little more than you are comfortable with. But you don't want to pass up the chance of owning this house since otherwise it's just so perfect for you.
The builders of the house (the original owners) mention that some of the other houses have alarm systems and that from what they've seen over the last two years, that alone seemed to be enough to discourage robbers from infiltrating their houses (another very real world situation of course). So you say to yourself, ok, I'll get the house, but I'll put the money to have a very good alarm system. You don't stop there, you've heard of other benefits of house automation and decide to automate your house in the process (hey you won the lottery, money's no object).
Now, to do that, you need to consider more than one thing. For example, how many ways are there to get into your
house? What kind of entry ways are there? What kind of sensor and/or contact do you believe you need in each room to keep them
safe and the like? And this is only for the Alarm System part. You also have to consider what home automation feature you
want to add to your house. For this part you basically simply have to think of what the features available are and if you want them
and where in the house would they be useful. Since money is no object we won't consider any pricing or costs (but it would be a good
add on feature for someone building house automation and alarm systems). So in this example, your house will have it all and this will be
described in the following section.
THE DREAM HOUSE DESCRIBED:
In order to know what's involved with this simulation project, let's start by describing the house you just bought a bit in detail to get a feel of everything that it has. We'll start with the basement and work our way up all the way to the second floor and the attic above it. This way, you'll know what is where in the house.
THE GROUND LEVEL (FIRST FLOOR):
This floor is the first to be seen by you and by guests. when they enter through the front door, the first thing they can see is the reading room and the stairs learning to the second floor on the left and a lighted room on the right (to take full advantage of the sunlight. At the end of the main hall they can spot part of the main dining area and if they walk forward, they can see the kitchen on the right and the main floor bathroom on the left. Here is the layout of this first floor.
RESIDENTIAL FLOOR LAYOUT First Floor 80' wide +-----------+----------+==========+----------+--------------------------+ | | Patio door | | | | | | | | +----------------------+ | | | | | + + | + | \ | | | Main \ Dining Area Kitchen | | + Bathroom + | + | | | | | | | | | | | | | | +----------------------+ | 60' | | | | depth | | | | +-----------+--------+-----+ +--------------------------+ | |-----| | | | |-----| | + | |-----| | | + |-----| | | | |-----| + + | Reading Room |-----| / Living Room | | |-----| / | + Library +-----+ + + | + + | | | \ \ | | | \ \ | + | + + | | +-----+ +-----+-----+==+==+-----++---++ ++---++ \ / Main Door \ / +----------+ +----------+ ENTRY POINTS: - Picture Windows left and right of the house - Main entrance door - Patio door in the dining area - Windows in the reading room, living room and kitchen - Window in the bathroom
THE HOUSE'S SECOND FLOOR:
On the second floor as soon as you come up the stairs you see two doors on the left one for the master bedroom and one for the master bathroom (so guests don't have to go downstairs if they need to go). In front of you is a sitting area just to sit and talk basically. On your far right is the guest room and beside that one, taking a lot of space, is the entertainment room (you need room to cram a pool table, home movie, stereo system and computer in there. Here's the layout of the second floor.
RESIDENTIAL FLOOR LAYOUT Second Floor 80' wide +--------------------+-------+-----+---------+---------+----+-----------+ | | | | | | Sitting | | | + Area | | | Master \ + + + Bathroom \ / Guest | | + / Room | | | + | + | | + +------+ +------+ | | | \ / | | | | \ / + | | + \ +---------+--------------------------+ 60' | \ | | depth | + | | | |-----+ | | | |-----| | | + |-----| + | | Master |-----| / | | Bedroom |-----| / Entertainment + + |-----| Room | | |-----+ \ | | | \ | | | + + | | | | + | | | | | | | | | | | +-----+ +----+----+---+---------------+ +-----+ \ / \ / +----------+ +----------+ ENTRY POINTS: - Picture Windows in the master bedroom and entertainment - Window behind the stair case - Window in the sitting area - Windows the guest room - Window in the master bathroom
Part of the basement is taken for the 3 car garages they take up the lower left side of the house. Behind it is empty space you use for storing stuff. The right side is an open area that can easily hold a good size wood workshop that you setup for your wood projects. Here is the layout of the basement. The only entry points to the basement (from outside) are the three garage doors. There are 6 small typical basement windows but they are too small for the average person to come through them hence one motion detector in the workshop area would do nicely. Here is the layout of the basement floor.
RESIDENTIAL FLOOR LAYOUT Basement 80' wide +----------------+---+---------------+------+---+------------+---+------+ | | | | | | | + | | First \ + | Garage \ / | + / | | + | | | + | | +------------------------------------+ | + | + | | | | + | | Second \ The | 60' | Garage \ Workshop + depth | + | | | | | | | + | | +------------------------------------+ | + | | | | | | + + | Third \ | | Garage \ +-----+ | | + +-----+ | | | +-----+ + | | +-----+ | | | +-----+ | +----------------+---+---------------+------+-----+----------+---+------+ ENTRY POINTS: - First garage door, window and door to workshop - Second garage door and door to workshop - Third garage door, window and door to workshop - Work shop door and six windows
The attic has no separations per se. The frame that makes up the rooftop is triangular. There is one small window and one vent on a wall. Since the vent is too small to let anyone in, the only entry point is the window. Now since it's in the attic one might think it's not obvious to get it. But a rather big tree on the side of the house managed to give access to that window rather conveniently. Hence we'll need one contact sensor for that window and a motion sensor as well since if they break the window instead of opening it they could do whatever they wanted from then on out.
THE HOME AUTOMATION FEATURES:
Home automation are systems that are designed to help make your life that much better and do things for you (much like the automation of many processes in businesses or others). There are many things that currently exist as far as home automation goes. So looking at the floor plans above let's see what we could add to make your life easier.
THE WINDOW TINTS:
When it's sunny outside sometimes (like at dusk or dawn) it can be annoying to get the sunlight directly in your face. Hence they have a system that can tint the windows according to the amount of sunshine that comes in the house. This can be quite useful as you can imagine. So you decide to put auto tint windows in your living room, dining area, reading room and the master bedroom.
AUTO LIGHTING FEATURE:
This is of course related to the alarm system to some degree. But imagine this, you wake up in the middle of the night and need to go to the bathroom. This feature will light up the lights as you walk from wherever you are to the bathroom. If you're the type to hit your toes in everything by the time you get there, this might help show you where these things are and avoid some unnecessary foot pains. So you add this feature outside so the light turns on when something moves around certain parts of the house as well as in some "trajectories" to and from the bathrooms of your house.
SIMULATED LIGHTING CONDITIONS:
This is typically a great tool against robbery. Imagine for a minute that you leave on vacation for 3 weeks. This feature could simulate life in your house while you're gone. It would turn on certain lights automatically at certain times as well as stereo systems, televisions and other equipment to give the impression that there's somebody in the house. Think this is taken right out of the science fiction channel? Think again, it exists, and has existed for at least 10 years now, But today, it's even more refined and perfected. So you decide to have that setup as well. Typically, this system will record your "weekly" schedule to know what to open when while you're gone.
AUTOMATED HEATING SYSTEM:
This is rather easy and simply involves you telling the system what time to raise the heat in the morning and what time to lower it at night (to save on your energy bill). You could probably enter some special conditions too so that if you do leave on vacation the house can keep itself running on the lowest setting (or turned off) in your absence. House automation isn't just for your comfort. Sometimes it's worth paying if it saves you on your bills on top of it. So yes, you of course have that in your system ready for action.
AUTOMATED OUTLET CONTROL:
Yes, that exists as well, they are devices you plug in your outlets on top of which you plug in your equipment. They essentially serve to control when they can be used. Hence, if you get someone to feed your pets or water your plants while you're gone on vacation. This would disallow them to use your computer or whatever else if you don't want them to. If you have kids, you could make it so they can't turn anything on passe a certain time or earlier than a certain time. Great for power management and for your ears especially when you're sleeping. This is, of course, very useful if you're the type to fall asleep to the television and leave it running all night long. It's not that expensive so you get enough of these for all your outlets.
PUTTING THE PUZZLE TOGETHER:
Now we have described our house, which possible ways there are to get in the house "uninvited" so to speak and we defined all the home automation features we want. You can imagine that each window and door learning outside needs a contact sensor. You also assume that if they break the window instead of opening it the contact is still there so you add some motion detectors in every room. There are probably other things you could do as far as alarm system and home automation goes but this tutorial can do fine with this much stuff so we'll leave it at that.
You, of course, already have fire and smoke detectors which are also connected to the alarm system and some thermometer and humidity sensors so you can keep those at ideal conditions. Now comes the part where you have to take all this stuff and make it work in a program. All this gets managed and controlled from a central console (and a wireless remote that can be used anywhere in the house). So assuming you have everything connected properly. The next step is to define our central console.
THE CENTRAL CONSOLE:
Because of the need to turn the alarm off when you get home, the central console is typically located near the main entrance. It has a clear lighted display that gives you plenty of information on what's going on (if anything) where in the house. It also has a keyboard so you can set things up in the system or change anything in the house on the fly. The central console has three main functions.
The system will be in monitoring mode by default. From there the user can take a look to see if anything of interest is currently happening somewhere in the house. Hitting the F2 key will put the system in setup/change mode. This mode is based on the rooms and areas of your house. Hence it will offer a list of these areas to the user. The user will then select the room they want to setup or change and will then go the tabs on the right where they can monitor or setup the security and home automation features they want for it. I think this will be the best and quickest way to move around in the system. We are now ready to start coding our simulation. We'll use some keys on the keyboard to simulate events so we see what happens. We'll also have special things to change the date and time so we can see how the home automation features work (if they do). And aside that we'll make ourselves a complete console program for the control and monitoring of everything we described here. So let's start the coding process.
THE HOME SETUP GENERAL INVENTORY:
Before anything else, let's take the floor plans and descriptions and take a look at the needed equipment for each of them. This will give us an idea of everything we'll need to cover for the whole house safety and automation features. Here's a table with the quantities of everything we'll need.
This is the set of equipment we will be setting up (simulating a setup that is) in your simulated house. We will need to add other sensors (that I'll describe in the next section) along with some other equipment to make it all stick together and work. Let's start by going over the types of sensors that are available.
THE TYPES OF SENSORS
Different types of sensors perform different kinds of functions. Though some are similar in nature, because of the part of the house they go on, their shape or strength of operation can vary. Let's review the different types of sensors and contacts you that are available to give you a better idea.
THE SECURITY CAMERAS:
Of course, you don't want to just discourage robbers to aim for your house, you go a step further and decide to help catch these robbers whenever you can. Hence, all rooms defined above have a hidden camera in them that is connected to the alarm system. Hence if any entry points are violated in any part of the house, the corresponding camera will begin to record for a specified amount of time. Each camera can be setup to record anywhere from 1 minute to 2 hours. Not only that, if the robber breaks another entry point that camera will also start recording. So your chances of identifying the robber will be that much better. So you have a camera setup in every zone (room) of the house.
And there you have it. With these sensors in place where they go and the system programmed accordingly you are now ready to secure and control your home. There are things you could add such as scheduled lawn watering (to keep it greener than your neighbors) and the likes. We are now at the point of actually starting to code our system. So let's start by defining our data.
THE CENTRAL CONTROL SYSTEM APPLICATION: (Mystik H.A.S.S.)
Mystik H.A.S.S. (Home Automation and Security System) is the name we'll call this project. Now since the main goal here is to automate the simulated house and also to plan for the future (if you add to the house for example) or if you buy a new house, I'll use data files for everything so you can add to them or change them to setup entirely different houses. This combined with dynamic arrays to load everything in RAM should offer a lean and efficient way to both setup your house and adapt the system to any other situation. Note that binary or random access files might do a quicker job in this case but for the sake of clarity of this tutorial I've selected text files so you can easily view their contents. Here is the list of files with their explanation.
On top of these we will have a file called simulationlogs.txt which we can review at any point to see what happened when during the simulation. Anything not recorded in these log files indicate that everything was running smoothly. Anything recorded is any situation that arises during the simulation (either random or triggered manually through the menu options and such. with this, we'll be able to view the results and make sure things happened when they were supposed to happen and for the right reasons.
AND TO CONCLUDE THIS SECOND PART:
And there you have it, this is the plan for the simulation program. I chose this type of project because I think it's safe to assume that most of us know what home automation and security systems are. Also, as you'll see in the next issue when I publish and document the code, there should be most part of any simulation in the code which should help use this as a base (a template if you will) for your own simulation projects.
As I mentioned in the beginning of this article, if you have any questions so far in this project description, be sure to email me and let me know because it's important that everything be clear upfront before we tackle the code base (in the next issue). Perhaps I haven't detailed a part of this enough and you'd like to know more about it, just contact me and I will detail it as much as I can so that everything is clear. Until next time, happy reading and coding.
Marrying YaBasic And Ubuntu: by E.K.Virtanen
SEC. TITLE: YaBasic for Ubuntu: How to.
Currently, YaBasic can be found in Ubuntu (Debian) repositories but sadly, it is pretty buggy version of it. However, PSnake did fix one of the biggest bug and YaBasic is very powerful and usable basic programming tool for basic lovers.
So here is a simple how-to, how you can get fixed version of YaBasic in
your Ubuntu easily. I also tell you how you can use Gedit as an IDE for
sudo apt-get install YaBasicIt is a good habit to backup things before we mess with them so let's do a backup of old YaBasic. Continue with your terminal and type next line too.
sudo cp /usr/bin/yabasic yabasicBUNow in your /usr/bin/ folder has backup of YaBasic, named as yabasicBU. After you have gone through this tutorial and sure your YaBasic works you can remove that backup file. 2. Now, point your browser to http://yabasic.basicprogramming.org/ and download latest stable release by new developers. You can extract it where ever you want. After extracting, go with your terminal there. Type next line in your terminal then.
sudo cp yabasic /usr/bin/This copies updated yabasic binary file to /user/bin and overrides old one. 3. Type yabasic in your terminal and add next line in YaBasic IDE
open window 100, 100and press enter twice. If you see a small gtk window opening, your YaBasic is ready to use.
SEC. TITLE: YaBasic and Gedit.
After Ubuntu 7.10 was released, gedit syntax files went so weird that I am not honestly aware how this should be done in 100% right way. However, i did next thing and well...everything seems to work fine. 1. I am pretty sure there is some syntax file for some language, what you don't need. For me, it is vb.net. So I decided to get rid of VB.NET and add YaBasic instead of it. Go to your terminal and type:
sudo gedit /usr/share/gtksourceview-2.0/language-specs/vbnet.langIMPORTANT: Be warned that with this guide, you will lose your original vb.net syntax file and it is replaced with a new one. If you hesitate then backup your vb.net lang file! Now, you see vbnet.lang file in you gedit editor. Replace it with this:
<?xml version="1.0" encoding="UTF-8"?> <!-- Author: John Luke <firstname.lastname@example.org> Copyright (C) 2008 John Luke <email@example.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --> <language id="vbnet" _name="yaBasic" version="2.0" _section="Sources"> <metadata> <property name="mimetypes">text/x-vbnet;text/x-vb</property> <property name="globs">*.vb</property> <property name="line-comment-start">'</property> </metadata> <styles> <style id="comment" _name="Comment" map-to="def:comment"/> <style id="string" _name="String" map-to="def:string"/> <style id="preprocessor" _name="Preprocessor" map-to="def:preprocessor"/> <style id="keyword" _name="Keyword" map-to="def:keyword"/> <style id="type" _name="Data Type" map-to="def:type"/> <style id="special-constant" _name="Special constant" map-to="def:special-constant"/> <style id="boolean" _name="Boolean value" map-to="def:boolean"/> </styles> <default-regex-options case-sensitive="false"/> <definitions> <context id="line-comment" style-ref="comment" end-at-line-end="true"> <start>//</start> <include> <context ref="def:in-line-comment"/> </include> </context> <context id="old-style-comment" style-ref="comment" end-at-line-end="true"> <start>rem</start> <include> <context ref="def:in-line-comment"/> </include> </context> <context id="string" style-ref="string" end-at-line-end="true"> <start>"</start> <end>"</end> </context> <context id="keywords" style-ref="keyword"> <keyword>fi</keyword> <keyword>endif</keyword> <keyword>elseif</keyword> <keyword>elif</keyword> <keyword>else</keyword> <keyword>if</keyword> <keyword>abs</keyword> <keyword>acos</keyword> <keyword>and</keyword> <keyword>arraydimension</keyword> <keyword>as</keyword> <keyword>asc</keyword> <keyword>asin</keyword> <keyword>at</keyword> <keyword>atan</keyword> <keyword>beep</keyword> <keyword>bell</keyword> <keyword>bin</keyword> <keyword>bind</keyword> <keyword>bitblit</keyword> <keyword>bitblit</keyword> <keyword>bitblt</keyword> <keyword>bitblt</keyword> <keyword>box</keyword> <keyword>break</keyword> <keyword>case</keyword> <keyword>chr</keyword> <keyword>circle</keyword> <keyword>clear</keyword> <keyword>close</keyword> <keyword>color</keyword> <keyword>colour</keyword> <keyword>compile</keyword> <keyword>continue</keyword> <keyword>cos</keyword> <keyword>curve</keyword> <keyword>date</keyword> <keyword>dec</keyword> <keyword>default</keyword> <keyword>do</keyword> <keyword>dot</keyword> <keyword>end</keyword> <keyword>error</keyword> <keyword>eof</keyword> <keyword>eor</keyword> <keyword>error</keyword> <keyword>execute</keyword> <keyword>exit</keyword> <keyword>exp</keyword> <keyword>export</keyword> <keyword>fill</keyword> <keyword>filled</keyword>