How to Program in Gasp
Gasp is a recursive acronymn for "Gasp! Another Silly Programming-language?"

If you already know how to program and you just want to learn Gasp really quickly, keep reading.  If you're new to programming, click here [todo: put a link here]. This document is intentionally dense, so I recommend digesting it slowly.

Some normal and nice things about Gasp:

Some unique and weird things about Gasp:

Hello World

To get started, open a text editor and paste in the following code.  Save it as hello.gasp.

class MyFirstClass(Object)
{
    proc main()
    {
        Console:c.set(null)
        c.print("Hello World\n")
    }
}

Now go to a command line and type:

Gasp.exe build hello.gasp

This will create a file called "Untitled.xlib".  You can rename it if you like.  Now type:

Gasp.exe run Untitled.xlib

You should see thisoutput:

Hello World

You have created a class named "MyFirstClass" that inherits from "Object". It contains one procedure named "main". You created a variable named "c" of type "Console" and set it to null. You used the empty "c" variable to call the "print" procedure which printed the message to the console window.  Note that "\n" indicates the line-feed character.

Rocket

Now let's step it up a notch.  Here's the code:

class Rocket(Object)
{
    proc main()
    {
        !Console:c.set(null)
        !Integer#i.copy(10)
        while(i > 0)
        {
            c.print(i)
            c.print("... ")
            &i.decrement()
        }
        c.print("Blast off!\n")
    }
}

Now build it:

Gasp.exe build rocket.gasp

Then run it:

Gasp.exe run Untitled.xlib

The output should be:

10... 9... 8... 7... 6... 5... 4... 3... 2... 1... Blast off!

Remarks:

We made a class named "Rocket" that inherits from "Object". (Object is the base class of all classes.) Again, the entire program consists of just one procedure named "main". The first line of code creates a variable named "c" of type "Console" so we can use it when we want to print text to the console.

The second line of code makes an integer and initializes it to 10. Let's break down this line a little bit:

First you need to realize that there's a difference between a "variable" and an "object". Variables have names. Objects have values. Variables are stored on the stack. Objects are stored on the heap. Variables disappear when you exit the scope. Objects disappear when no variable references it anymore. It's possible for many variables to reference the same object. Variables and objects are not the same thing. Don't mix them up or you'll have a hard time understanding this language.

You create a variable when you use a ":". You create an object by calling the "new" method. It's very common to see a line like this:

!Integer:i.new()

This will create a new variable of type "Integer" named "i" and set it to reference a new Integer object. Since the value of the object is not specified, so it will be initialized to zero. Since it's so common to call "new" to make a new object after you use ":" to make a new variable, there's a short-hand way to do it:

!Integer#i

So the "#" creates a new variable and calls the "new" method. But we also want to initialize the value of the Integer object to 10, so we add a call to the "copy" method:

!Integer#i.copy(10)

Note that we could have done the same thing with two lines of code like this:

!Integer:i.new()
&i.copy(10)

Now you're probably wondering what's up with the "!"s and "&"s. By default, all variables and objects in Gasp are "read only". That means you can't change them. (It's a very paranoid language.) A "!" makes a variable temporarily writeable. A "&" makes an object temporarily writeable. Any time you are going to change what a variable references, you need a "!". Any time you are going to change the value of an object, you need a "&".

A "!" refers to the first variable that comes after it. For example, in this line...

!Integer:i.new()

...the "!" makes "i" temporarily writeable. "Integer" is not a variable, it's a type, so the "!" doesn't affect it. Why don't we just put the "!" immediately in front of the "i"? Well, that would be confusing because it would think you were trying to create a variable named "!". When you use a "&", it makes the object referenced by the next variable temporarily writeable. For example in this line...

&i.copy(10)

...the object that is referenced by "i" is temporarily writeable so that we can change its value to 10.

Operators:

Expression Modifiers
&         The object may be modified
!         The variable may be modified

Variable Operators
:         Make a new variable
#         Make a new variable and call the parameterless "new()" method
.         Dereference member

Comparison Operators
==         Variables reference the same object
!=         Variables reference different objects
=         Objects have same value
<>         Objects have different value
<         Object value less than
>         Object value greater than
<=         Object value less than or equal
>=         Object value greater than or equal

Arithmetic Operators
+         Plus
-         Minus
*         Times
/         Divide
%         Modulus
^         Xor
|         Or
&         And
?         Maximum
~         Minimum

Bank

Here's the code:

class BankAccount(Object)
{
    !Float:balance

    method !new()
    {
        !this.allocate()
        !this.balance.new()
    }

    method &transaction(Float:amount)
    {
        &this.balance.add(amount)
    }
}

class Person(Object)
{
    !String:name
    !BankAccount:account

    method !new(String:name, BankAccount:account)
    {
        !this.allocate()
        !this.name.new()
        &this.name.copy(name)
        !this.account.set(account)
    }
}

class SomeClass(Object)
{
    proc main()
    {
        // Make three bank accounts
        !BankAccount:account1.new()
        !BankAccount:account2.new()

        // Make three people
        !Person:merchant.new("Shylock", account1)
        !Person:husband.new("Antonio", account2)
        !Person:wife.new("Portia", account2)

        // Husband earns money at work
        &husband.account.transaction(100.0)

        // Wife spends money at the mall
        &wife.account.transaction(-99.99)
        &merchant.account.transaction(99.99)

        // Husband checks his balance
        !Console:c.set(null)
        c.print(husband.account.balance)
    }
}

Here's the output:

0.01

Remarks:

This program has three classes. It demonstrates how to make your own class, how to use member variables, how to use methods, the "set" method, and some other things.

In the "Rocket" example we used the "copy" method. In this example we use both "copy" and "set". "copy" changes the value stored in an object. "set" changes the object that a variable references. So you need a "&" to call "copy", but you need a "!" to call "set". Be very careful not to mix the two up. You should use copy when you want to make another copy of some value. You should use set when you want to set some variable to reference the same object as another variable.

In this example we used floating point numbers instead of integers. When you specify a constant floating point value, you must include a decimal point in the value, even if one is not needed. If you don't, the compiler will interpret it as a constant integer and will complain about it.

Now let's talk about methods. A "method" is similar to a "proc" except that a method has one implicit parameter named "this". The type of the "this" parameter is the class in which the method is found. When you put a "!" or a "&" in front of a method name, it modifies the implicit "this" parameter. So for example, the method "BankAccount.new" has an implicit first parameter of "!BankAccount:this". "BankAccount.transaction" has an implicit first parameter of "&BankAccount:this". And "Person.new" has an implicit first parameter of "!Person:this".

Most object oriented languages implicitly call a "constructor" method when you allocate an object. Gasp does the reverse. First you call some method and that method will explicitly allocates itself and set the "this" variable to reference it. (That's what the "allocate" method does. Any method that calls "allocate" could be termed a "constructor". There's nothing magical about the name "new". It's convention to name such methods "new", but it would work just fine if you named them something else.) Most oo languages treat the implicit "this" parameter as a special case and do not let you modify it. Gasp treats it just like any other parameter: you can change the values of the object it references if it's declared with a "&" and you can even change the object it references if it's declared with a "!".

After a method calls "allocate", it will typically want to allocate an object for each of its member variables. If the member variable is declared with a "#" instead of a ":" then an object will be implicitly allocated for that member variable when "allocate" is called. (Unfortunately that feature was not supported yet when this document was written, so for now you need to use a ":" for member variables and allocate them yourself after you call "allocate".) In this particular case, however, the husband and wife wish to share the same bank account. So instead of creating a new "BankAccount" object in "Person.new", we simply set the Person.account variable to reference the account that was passed in as a parameter. This way the caller of Person.new can decide which account is associated with the new person. (Note that SomeClass.main creates three Person objects, but only creates two BankAccount objects.)

Advanced

Now that you understand the basics, you can learn about the other features of the language in pretty much any order you want:

[todo: write a section for each of these features]

Getting Familiar with the Class Library
Interfaces
Abstract Methods
Calling from Gasp to C++ code
Calling from C++ to Gasp code
Exception Handling
Threading
Advanced Garbage Collection
Performance
XLib Structure
The Disassembler
The Debugger
The Engine
etc.
 

 



SourceForge.net Logo