Showing posts with label basic. Show all posts
Showing posts with label basic. Show all posts

Tuesday, January 16, 2024

The Heart Behind Liberty BASIC

 As the creator of Liberty BASIC, I want to share the story behind this programming language, a project born out of my passion for making programming accessible, fun, and wondrous for everyone.  My journey in the realm of coding began with the magical experience of BASIC, a language that opened the doors to the world of software creation for me. I want to bring that same sense of excitement and possibility to others through Liberty BASIC.

What makes this especially inspiring I think is that Liberty BASIC was originally meant to be a programming game, where the player programmed robots in BASIC.

Bringing Back the Magic of BASIC

When I realized that the BASIC I was writing for the robot game would become a real programming tool, I decided to go for it!  My idea for Liberty BASIC was to recapture the spirit of the early days of BASIC. BASIC was the gateway for many into programming. It was simple, inviting, and allowed immediate interaction and results. My vision was to reignite that spark of wonder, making programming as much fun as it was for me when I first started.

Simplicity and Approachability

At the heart of Liberty BASIC lies its simplicity and approachability. The language is designed to be easy to learn and use, especially for those who are new to programming. It’s like giving someone a set of simple, intuitive tools to start building their dream projects right away.

Fun and Immediate Results

One of the unique features of Liberty BASIC is how it makes programming fun. I believe in the power of seeing your work come to life quickly. Beginners should be able to write a few lines of code and immediately see a window pop up, a graphic drawn, or a simple game come to life. This immediate feedback is not just rewarding; it's crucial in maintaining enthusiasm and interest in learning.

Liberty BASIC vs. Other Languages

While other languages like Python and JavaScript are powerful and versatile, they can be daunting for beginners.  I've always tried very hard to balance simplicity with capability. 

My Vision and Journey

My personal journey with programming has always been about the joy of creating and of learning new ways to think. With Liberty BASIC, I wanted to offer a tool that makes programming feel like an adventure, not a chore. It's been heartwarming to see people of all ages take their first steps in programming with Liberty BASIC, discovering the same joy and wonder that I found years ago.

In essence, Liberty BASIC is more than just a programming language; it's a celebration of the simplicity, fun, and wonder that programming can bring. It's been a wonderful journey that I am eager to invite others to join.

Links

        Liberty BASIC website 

        Liberty BASIC community forum  

        Liberty BASIC video playlist  

Saturday, October 08, 2022

The Enduring Appeal of BASIC

 Back in 2018 I started the BASIC Programming Language group on Facebook.  Since then it has grown to more than 7000 members, and the posting has only accelerated.  What I find really interesting about it is that the membership suddenly began to grow very rapidly in the last few months, more than doubling.

When a member wants to post for the first time there are a couple of questions that they need to answer, and I approve or deny the right to post based on the answers, the other groups the person belongs to and I also factor any pending comments.  The overwhelming majority of the requests to post are approved.

One of the questions is, what is your first BASIC or your preferred version of BASIC?

It becomes clear that there are so many different versions of BASIC that people use and have used.  I find this to be very impressive.  Additionally there are a bunch of people in the group who have written their own versions of BASIC, including myself (Liberty BASIC).  This sort of thing is continually ongoing.  BASIC is not a dead language at all!

Another important thing is that there are people of all ages all over the world who are still using and learning BASIC.

Wednesday, September 22, 2021

End User Programming - Real Computer Literacy

Most people will agree that it is good to understand the mechanical working of cars if you are going to drive one. It helps you to drive more safely, and if you break down somewhere you stand a chance of helping yourself out of a tough spot. When you go to the mechanic you will be able to avoid being ripped off by unscrupulous people.

It is no different with computers. If you learn to program computers it helps you to take advantage of them, and not the other way around. This is the real computer literacy; not the ability to operate a tablet or cell phone, or to know your way around the preferences or control panel of Windows or Mac OS. Many times I see people praising this kind of feature knowledge by young people. "Oh, young people are so smart. When I have a problem with my phone I ask my kids for help." We need to give them more than that, or else they may think more highly of themselves than they ought to.

So, what vehicle can we use to give computer literacy to the people? Computer programming is the critical thing because it gives the user a real understanding of computers. For the average person to attain programming skills we don't need a complicated enterprise grade programming language, which would frustrate more than enlighten people. BASIC was the engine for people to learn programming in the early days, and still could be if Windows, Mac and Linux would just include it.  Easy programming languages are missing or hidden from the user, and this causes a very real harm.

Why don't people create their own software anymore? They don't feel the need for it. They can just buy what they need.  While this is true, there are so many times when packaged software doesn't do exactly what is needed. There are also so many kinds of useful software that could be written that will not make it onto store shelves.

In fact they may even wonder why they should bother. They aren't encouraged to learn programming anymore like they once were. They don't know what they're missing if you ask me. Programming is a much better way to spend brain cells than watching TV or surfing the web. Personal computing was envisioned as a way to bring the power of the computer to the individual, a very empowering idea. Being limited to using prewritten applications is like being told that as an artist you're only allowed to paint by numbers.

So we need an easy way to start programming. It can be really hard to create software with the programming languages endorsed by the mainstream.  We have gotten away from simpler languages like BASIC, perhaps under the assumption that more complexity is better, but good computing avoids needless complexity.  Even with a language like Python there is too much to learn before you get results.  The Raspberry Pi computer, a device popular in schools, is a strong device for many purposes but it is too complicated to be a foundation for teaching computing to K-12 or as a first programming tool for most adult beginners.

Computers don't come with an easy to use programming language anymore.  This is SOOOO important. It used to be that when you turned the average computer on, the first thing it did was start BASIC. You could start programming immediately, and it was very easy to pick up. Nothing bad happened if you made a mistake, and it was fun!

People like to say that BASIC is a bad language for teaching programming.  The early versions of BASIC do have their weak points, but newer versions of BASIC are very strong for students and end users.  An entire industry of computer software came out of young people using computers that started up in BASIC programming mode.

Thursday, November 07, 2019

One Role Per Subroutine/Function - Best Practices Series


If I write the following code:

  call openFile "myFilename.dat"
  call writeDataToFile
  call closeFile

I have three different subroutines that I am calling.  The first call should open a file name named myFilename.dat.  It should not do anything unrelated to opening that file.  The writeData call should only write data to the file.  The closeFile call should only close the file.  These subroutines might have some related code that makes sense for dealing with files specific to the application, or some debug logging code or the like and that would probably be fine.

But if sub openFile also opens a graphics window, or if it reinitializes a bunch of variables, or anything else that is not directly related to opening the file, that code is probably in the wrong place.  Such code should be moved to its own subroutine.

Why is this important?

One important idea in software development is called the principle of least astonishment.  As much as possible when I read code I expect that it should do precisely what it appears to be doing.  Nothing more, and nothing less.  Trying to avoid "What the ..!?" moments is an important goal in programming.  It saves time and money and makes people's lives easier.  :-)

Sometimes code is initially written very clean and in a way that is compatible with this idea of one role per subroutine or function but over time it gets polluted and things get into the code which violate this principle.  This is especially common when debugging because it's easy to write code during a heavy debugging session that you would not normally be willing to write when you're not debugging.  Then once the bug seems to be gone we are less willing to move that 'debug quality code' to the place where it belongs, or we are not sure how to do it.

Of course if you write a program such that there are no named subroutines or functions then your program is in danger of being a Big ball of mud (see https://en.wikipedia.org/wiki/Big_ball_of_mud).  If you discover that this is the state of your work, your code can be greatly improved by beginning to identify sections of code that can be moved into named subroutines or functions.

As a counterpoint this idea if you find that all the programs that you write are small one page long games or utilities that you bang out in a few minutes, then your programs might only be a small ball of mud.  In this case you might not really benefit very much from trying to break everything down into small named subroutines.

Tuesday, November 05, 2019

Naming Things Well - Best Practices Series


Some BASIC programmers come from the experience of needing to fit their programs in 4K of RAM or less, so it feels natural to give variable names single letters such as a, b, c or I, j, k. Of course most classic BASIC interpreters don't have support more for than 2 characters for variables. Some BASICs will let you call your variable 'count' but only the c and o will be recognized as the variable name.

To be fair, I've seen more than a few C programmers also choose single character variable names. Bad habits are language agnostic. ;)

In programming languages today including Liberty BASIC, you can give your variable names and other things such as subroutines and functions longer names. What's more, computers have so much memory that we can dispense with trying to save memory with short variable names. And if you're used to using line numbers I strongly encourage you to discard them in favor of named labels. Once you are used to this it will make your programming better.

Why does it matter?

Programming is an exercise in thinking and so it is really important to pick the best possible names for the parts of your programming ideas. When you or somebody else reads your code it will help to understand the code if the variables and function/sub names are chosen well.

What if you are about to go to the store to buy some milk and you told your friend "I'm g to the s to b some m." How well would you be understood?

So, when you write code ask yourself (or the coder next to you) what is the best name for this variable or routine? Later on you may even realize there is a better name and so don't hesitate to act on that impulse and update your code with the new better name.

Think of your coding as a journey to discover the truth of the code, and naming things is an important part of the discovery.

Friday, October 26, 2018

No Software Degree? Don't Let It Stop You!

I saw a an article over on freecodecamp.org where the author tells his story about getting a development job without a degree.  I think it is so inspiring when people share their stories.

I also am an un-degreed software engineer and I’ve been working in the industry for more than 30 years.

I assume that if you are ready to jump in to software development without doing a 4 year program, that you are passionate about writing code! If that describes you, read on!

Here are some tips.
  • Don’t let anyone tell you that you NEED a degree. You can go and get one, sure and if that’s what you want, great. Go do it, but it will take you years and a lot of money.
  • Read a lot. Consume as much programming literature as you can. Read conference proceedings. Read code. Read the History of Programming Languages, read archives of Dr. Dobbs Journal. 
  • Learn several programming languages in different paradigms. I’m familiar with BASIC, 6502 assembly, Forth, C, Objective-C, Java and Smalltalk. Don’t be a one trick pony.
  • Make your own software. Participate in open source projects so you can learn team programming skills. Code with friends. Create your own applications. Write some video games. Try your hand at programming tools. I wrote Liberty BASIC (a popular programming language) in my spare time and now I sell it. If you have a dossier of interesting stuff that you’ve done, it will be easier to get hired. Haven’t done anything interesting? The degree may not be enough.
  • Network like crazy. Almost every job I’ve landed I landed because of people I met at the store, at church, at conferences (that I paid to attend myself), etc.  Join some programming groups on Facebook and meet local people using meetup.com.  This can be really important.
  • Be ready to explain what you know. When you do get that interview, who will hire you if you can’t show on the whiteboard what you learned from your work. Give them a post mortem on your own code. Be ready to say what you could have done better.
Good luck and please check out my Liberty BASIC product!  http://www.libertybasic.com
See you around!

Wednesday, August 02, 2017

Raspberry Pi Deluxe Starter Kit Giveaway!



We are giving away a deluxe Raspberry Pi kit, and this includes all kinds of nice accessories including an electronics learning lab.  No purchase is required, so enter by Aug 31, 2017 to be included in the raffle.

Check out the video here for details about the kit!  https://youtu.be/toln-Z_z4RY

To enter the drawing, send an email to carlg@justbasic.com with the subject Raspberry Pi Contest, and we will send you a confirmation email. The winner will be announced at the end of August 2017.

Please share this information with your friends.




Tuesday, August 02, 2016

Blast from the past - Whatever happened to PEEK and POKE?

I am reposting the following blog entry from ten years ago because it has been one of the most popular posts ever according to Blogger's statistics graph.  The link at the end of the post was broken, so I updated it.

Enjoy!


Sometimes I'm asked how to PEEK and POKE using Liberty BASIC. The short answer to this is, you can't. The long answer is more complicated.

The original home computers (like the classic Commodore 64, TRS-80, and Apple II models) were designed to be completely open to their owners. Most of the different parts of the computer like the sound, graphics, keyboard and joystick (there were no mice back then) were controlled by mapping them to different memory locations. So, the built-in commands didn't do everything you need? It was common to control the computer's equipment directly by sticking values into the memory locations that control that equipment, and reading the status back out. This was done with POKE and PEEK. This was a lot of fun, and usually useful too.

Since these early machines didn't multitask it was pretty safe to steal control of things away from the BASIC interpreter (which was a much operating system as there was). Then computers started running Windows, the Mac OS, Linux, etc. and allowed more than one program to run at a time. PEEK and POKE became problematic because if one program decided to mess with the screen for example, it might interfere with what other programs need to do their thing. Not only that, but computers today all have different kinds of hardware in them, so even if you could PEEK and POKE the exact memory locations would be different from machine to machine. So that's the bad news. :-(

The good news is that we can still have a power trip. How? Your operating system manages all the hardware for you behind operating system functions. These functions make every computer look more or less the same to the programmer. You can use these functions to do a lot of powerful things and most languages have a way to use them. For example Liberty BASIC programmers can use the CALLDLL command to make Windows API calls, which are the operating system calls of the Windows operating system. These are more complicated in general (and you can fill a whole bookshelf with information about them) than the old fashioned PEEK and POKE, but at least we aren't left without some way to pull rank on our computers. ;-)

So if you're missing the power and coolness of PEEK and POKE, why not try your hand at API calls?

Here is a useful link to get you started:

http://www.libertybasicuniversity.com/lbnews/nl108/index.htm

Friday, July 15, 2016

Dictionary lookup - getting the keys

When you have an array you can simply loop through the contents to examine what's there, but when you have a dictionary you need to have the list of keys so that you can look up each value in the dictionary.  For that, we need a getKeys$() function.  The following function returns a single string with the keys from our global dictionary$ variable, each separated by a delimiter that we can specify.

function getKeys$(delimiter$)
  pointer = 1
  while pointer > 0
    'get the next key
    pointer = instr(dictionary$, "~key~", pointer)
    if pointer then
      keyPointer = pointer + 5
      pointer = instr(dictionary$, "~value~", pointer)
      key$ = mid$(dictionary$, keyPointer, pointer - keyPointer)
      if instr(keyList$, "~key~" + key$) = 0 then
        getKeys$ = getKeys$ + key$ + delimiter$
        keyList$ = keyList$ + "~key~" + key$
      end if
    end if
  wend
end function

Once have this string we can tease out each key.  Here is an quick example that shows how to do this.  The variable allKeys$ will hold all the keys, each separated by "~".  Then we use the word$() function to get each key.

global dictionary$

call setValueByName "first", "Tom"
call setValueByName "last", "Thumb"
call setValueByName "phone", "555-555-1234"

allKeys$ = getKeys$("~")
print allKeys$

key = 1
while word$(allKeys$, key, "~") <> ""
  key$ = word$(allKeys$, key, "~")
  print "Key number "; key; " is "; key$
  print "    value = "; getValue$(key$)
  key = key + 1
wend


Here is what the resulting output looks.

phone~last~first~
Key number 1 is phone
    value = 555-555-1234
Key number 2 is last
    value = Thumb
Key number 3 is first
    value = Tom


Notice that the keys do not come out in the order that we put them in.  This is typical in dictionary style lookup mechanisms.  The ordering of keys is not guaranteed.

Tuesday, July 12, 2016

Liberty BASIC on the Rosetta Code site

One of the members of our community forum posted about some graphics code that he wrote on the Rosetta Code site.

Here is his post.
http://libertybasic.conforums.com/index.cgi?board=LB3&action=display&num=1468265910

I'm glad he posted about it just as a reminder to what a great resource the Rosetta Code site is.  There are many, many code samples there to learn from.  Check out this link.

http://rosettacode.org/wiki/Category:Liberty_BASIC

And, if you'd like to get in on the action there are many Rosetta Code examples which have not yet been implemented in Liberty BASIC.  For a list try this link:

http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_Liberty_BASIC

These are implemented in other language on the Rosetta Code site so if you'd like to try your hand at writing one or more in Liberty BASIC there are examples to glean inspiration from.

Monday, July 11, 2016

Dictionary lookup - Garbage collection

If we need to use our keyed dictionary lookup functions for a purpose where we will change the values for any or all keys the string we save in dictionary$ will get larger each time we set a key and value.  This is because the setValueByName subroutine sets a key and value by adding onto the front of the dictionary$ variable but it does not remove any preexisting value for that key.  So if for example I set a key of "storeFolder" and a value of "c:\myStoreFolder" and then later I change the value to "c:\myOtherFolder" I will have two different entries for the key "storeFolder".  Only the latest value will be returned by the getValue$() function.

So, how do we fix this?  We implement a garbage collector.  We can create a subroutine that makes a copy of dictionary$ that only has the latest value for each key.

Here is a first stab at a garbage collector subroutine.

sub collectGarbage
  pointer = 1
  while pointer > 0
    'get the next key
    pointer = instr(dictionary$, "~key~", pointer)
    if pointer then
      keyPointer = pointer + 5
      pointer = instr(dictionary$, "~value~", pointer)
      key$ = mid$(dictionary$, keyPointer, pointer - keyPointer)
      if instr(keyList$, key$) = 0 then
        value$ = getValue$(key$)
        newDictionary$ = "~key~" + key$ + "~value~" + value$ + newDictionary$
        keyList$ = keyList$ + key$
      end if
    end if
  wend
  dictionary$ = newDictionary$
end sub

Friday, July 08, 2016

Keyed dictionary lookup in Liberty BASIC

Liberty BASIC has a way to manage collections of data by using arrays and you look up the information by numeric position.  You can do a lot with this but it doesn't let you look up information by name.

We can provide an easy to use way to do this in Liberty BASIC by using the string functions of Liberty BASIC.  By using a single string we can have easy lookup of values by name and also have the ability to store the collection of values in a file and retrieve it simply.  In some versions of BASIC this is only useful for small lists of information because of string size limitations of 255.  Liberty BASIC permits strings of millions of characters so this is not a problem.

Here is a very simple demo of the concept just to get us started.  In future postings we will explain and enhance the way this works.

global dictionary$

call setValueByName "first", "Tom"
call setValueByName "last", "Thumb"
call setValueByName "phone", "555-555-1234"

print getValue$("last")
print getValue$("blah")
print getValue$("phone")
print getValue$("first")

sub setValueByName key$, value$
  dictionary$ = "~key~"+key$+"~value~"+value$+dictionary$
end sub

function getValue$(key$)
  getValue$ = chr$(0)
  keyPosition = instr(dictionary$, "~key~"+key$)
  if keyPosition > 0 then
    keyPosition = keyPosition + 5  'skip over key tag
    valuePosition = instr(dictionary$, "~value~",  keyPosition)
    if valuePosition > 0 then
      valuePosition = valuePosition + 7   'skip over value tag
      endPosition = instr(dictionary$, "~key~", valuePosition)
      if endPosition > 0 then
        getValue$ = mid$(dictionary$, valuePosition, endPosition - valuePosition)
      else
        getValue$ = mid$(dictionary$, valuePosition)
      end if
    end if
  end if
end function

Tuesday, January 19, 2016

Copying a folder full of files in Liberty BASIC

Over on the Liberty BASIC forum at conforums.com one member was asking how to copy all the files in a folder for a database.

The hard way is to use the FILES statement and to write a bunch of code that tests and loops.

But is there an easier way?

One solution is to use the SHFileOperationA API call.

CallDLL #shell32, "SHFileOperationA", SHFILEOPSTRUCT as struct, CopyFolder as long
Chris Iverson shows how in his post.  That and more in this thread.  Click to read.



Friday, January 15, 2016

Date is between function in Liberty BASIC

Someone recently asked me if Liberty BASIC can answer the question about whether a date is between two other dates.  Yes it can!

The following is my quick solution to his question.

answer = isDateBetween("12/21/2015", "12/15/2015", "12/30/2015")
if answer then print "yes" else print "no"


answer = isDateBetween("11/21/2015", "12/15/2015", "12/30/2015")
if answer then print "yes" else print "no"


function isDateBetween(aDate$, firstDate$, lastDate$)
    aDays = date$(aDate$)
    firstDays = date$(firstDate$)
    lastDays = date$(lastDate$)
    isDateBetween = firstDays < aDays and aDays < lastDays
end function


Enjoy!

Thursday, January 14, 2016

Tiny BASIC part 5 - Adding color to PSET

It's much more fun to draw in color than with only a black pen, so let's add a third parameter to the PSET statement for color, for example:
PSET x, y, "color"
To do this we need to add some code to our  case "pset"  block:
 CASE "pset"
  IF GWINOPEN = 0 THEN
    E$ = "PSET error - Graphic window is not open"
    GOTO [Ready]
  END IF
  GOSUB [GetExpression]
  IF E$<>"" THEN [Ready]
  PSETX = N
  GOSUB [GetChar]
  IF C$ <> "," THEN
   E$= "Comma expected after x parameter"
   GOTO [Ready]
  END IF
  C = C + 1
  GOSUB [GetExpression]
  IF E$<>"" THEN [Ready]
  PSETY = N
  PSETCOLOR$ = "black"
  GOSUB [GetChar]
  IF C$ = "," THEN
   C = C + 1
   GOSUB [GetStringLiteral]
   IF E$ <> "" THEN [Ready]
   PSETCOLOR$ = B$
  END IF
  #GWIN "color "; PSETCOLOR$

  #GWIN "down ; set "; PSETX; " "; PSETY
  GOTO [FinishStatement]

The way this works is that it will look for a comma and a string expression after it sets PSETX and PSETYIf there is no comma it will skip over the part that gets a color parameter, so the default color will be black in that case.

The string will be the name of a valid Liberty BASIC color, for example red, blue, green, black, etc.    The following code is stolen from the routine that parses for the PRINT statement.  In a later post we will incorporate this into the PRINT code by calling it as a subroutine so that we won't have the same code twice.
[GetStringLiteral]
  GOSUB [SkipSpace]
  GOSUB [GetChar]
  IF C$=G$ THEN
   B$=""
[NextStringMember]
   C = C + 1 : C$=MID$(A$,C,1)
   IF C$="" THEN
    E$="Unterminated string"
    RETURN
   ELSE
   IF C$<>G$ THEN
    B$=B$+C$
    GOTO [NextStringMember]
   END IF
  END IF
  C = C + 1 : C$=MID$(A$,C,1)
  IF C$=G$ THEN
   B$=B$+C$
   GOTO [NextStringMember]
  END IF
 END IF
 RETURN

So we call the [GetStringLiteral] subroutine and check E$ for an error.  If there is none then we set PSETCOLOR$ to the value of B$ as shown here.

   GOSUB [GetStringLiteral]
   IF E$ <> "" THEN [Ready]
   PSETCOLOR$ = B$
  END IF
  #GWIN "color "; PSETCOLOR$


Then we add a drawing command like so to set the color:

  #GWIN "color "; PSETCOLOR$

Here is a sample that uses PSET with color!


5 graphicwin
10 pset x, y, "red"
20 pset x + 10, y, "blue"
30 pset x + 20, y, "green"
40 x = x + 1
50 y = y + 2
60 if x < 100 then goto 10

And here is a screenshot!



Wednesday, January 13, 2016

Liberty BASIC file type association

Liberty BASIC doesn't map the BAS file extension to itself when it is installed.  This is because I didn't want to be so presumptuous as to steal a common file type away from another version of BASIC that might be installed.

So, because there is a bug in Windows which makes it really hard to remap a file extension and there have been discussions about this in the Liberty BASIC forum at conforums.com one of our member Chris Iverson (thanks Chris!) has contributed some Liberty BASIC code to solve this problem.

  Click to see thread in the forum

Enjoy!

Sunday, January 10, 2016

Lunar lander revisited

Liberty BASIC comes with a nice introduction to video games called lander.bas.
  • It's a good example of a timer driven game.
  • It uses sprites which are actually generated on the fly using turtle graphics.
  • It also shows proper technique of structured programming.
So I have some ideas that I am thinking about implementing to update it and make it an even more complete video game example:
  • Add sound effects including ambient sounds, rocket motor noise and crash explosion.
  • Animate the rocket motor so you can see rocket exhaust coming out.
  • Add some flying space junk sprites that you need to avoid while trying to land.
  • Add a colored starfield in the background.
Looking forward to this!  Check back for updates!

Friday, January 08, 2016

Tiny BASIC part 4 - Adding a PSET statement


Okay, now we are ready to add a PSET statement for drawing pixels.  Today we will simply add the ability to draw a single black pixel at a time.  Next time we will add color!

Here is the code to accomplish this.  This is just another SELECT CASE block to add after the one we added for the GRAPHICWIN command.
 CASE "pset"
  IF GWINOPEN = 0 THEN
    E$ = "PSET error - Graphic window is not open"
    GOTO [Ready]
  END IF
  GOSUB [GetExpression]
  IF E$<>"" THEN [Ready]
  PSETX = N
  GOSUB [GetChar]
  IF C$ <> "," THEN
   E$= "Comma expected after x parameter"
   GOTO [Ready]
  END IF
  C = C + 1
  GOSUB [GetExpression]
  IF E$<>"" THEN [Ready]
  PSETY = N
  #GWIN "down ; set "; PSETX; " "; PSETY
  GOTO [FinishStatement]
This was a bit tricky to write because there isn't really any documentation with the original Tiny BASIC source code, but by looking at the code for the other statements I think I figured it out correctly.  It does seem to work.

The syntax for the new statement is PSET x, y

Let me explain what it does.
  • First check to see if the graphic window is open.  If it isn't then set E$ to be an error string.  Then GOTO [Ready].  This will display the error.
  • Then get the next expression using GOSUB [GetExpression].  This unleashes the expression parser which is easily the largest and most complex part of the Tiny BASIC source code.  Then it checks for an error using IF E$<>"".  If E$ does contain an error, then GOTO [Ready].
  • Okay so got this far, so set PSETX to be what was in N, which is the result of the call to [GetExpression].
  • Now get the next character, which we expect to be a comma to separate the x and y values.  If the next character is not a comma, set E$ to be an error and GOTO [Ready].
  • Now advance C one character by adding 1 to it.  We do this because we found the expected comma, and now we need to skip over that so that we can get the next expression for our y value.
  • Get the next expression using GOSUB [GetExpression].  Test E$ for an error and GOTO [Ready] if there is one.
  • Get the value of N and put it into the variable PSETY.
  • Finally, draw the pixel in the graphics window!
Here is the sample Tiny BASIC program that uses the PSET statement:

10 graphicwin
20 pset x, y
30 x = x + 1
40 y = y + 2
50 if x < 200 then goto 20

And here is the output of the program!

Thursday, January 07, 2016

Run BASIC Revisited - The easiest web development system on Earth

I got an inquiry yesterday about Run BASIC asking about what is special about it.  The essential concept is that it is an all-in-one BASIC web application server.  You can use it to create a dynamic web site, or to host in-house applications for your business or school, or use it to control your home.  The possibilities are pretty much endless.

Here is a link to a white paper about Run BASIC.
    http://www.libertybasic.com/RunBASICBreakthrough.pdf

Here is a link to the Run BASIC community forum.
    http://runbasic.proboards.com/

Wednesday, January 06, 2016

Tiny BASIC part 3 - Adding GRAPHICWIN statement


We are going to add GRAPHICWIN and PSET statements to Tiny BASIC.

Let's start with the really easy one.  We will add a  case "graphicwin"  block to the end of the select case blocks that we examined in the last post.  Here is what it looks like.  The new code is in bold red.
 CASE "let"
  GOSUB [GetLabel]
  IF E$<>"" THEN [Ready]
 CASE "graphicwin"
  IF GWINOPEN = 1 THEN
    PRINT "Graphics window is already open."
  ELSE
    GWINOPEN = 1
    OPEN "Graphics" FOR graphics AS #GWIN
  END IF
  GOTO [FinishStatement]

 END SELECT
So when you run Tiny BASIC and type the command graphicwin and press Enter it will open a small graphics window.  When it does this it also sets the GWINOPEN flag to 1 to that we can check it if the program tries to open another graphics window.  Only one graphics window will be allowed at a time.

The other thing that we want to do it close the graphics window and reset GWINOPEN to 0 if the program is started using the RUN statement.

So, we need to add the following code into the  case "run"  block.  Here is how that code should look.  The new code is in bold red.

 CASE "run"
  IF GWINOPEN = 1 THEN
    CLOSE #GWIN
    GWINOPEN = 0
  END IF

  FOR I=27 TO 52 : A(I)=0 : NEXT I
  L=27 : C=1
  GOTO [FinishStatement2]
So now the program will always start off in a clean state each time it is run!

In our next post we will figure out how to add a PSET statement so we can draw some graphics!