Skip to content

Getting Started

Dylan Tuttle edited this page Sep 11, 2022 · 5 revisions

Welcome to soup!! Thank you for your interest in trying it out.

First, ensure you've installed the compiler.

Now we can get started!

Hello World

Let's write your first program! Create a file called helloworld.soup on your machine, and write the following lines:

func main() returns void {
    printf("Hello, world!\n");
}

Now open a terminal in the same directory as your new helloworld.soup file and enter the following command:

soup helloworld.soup

And you should see the following output in your terminal:

Hello, world!

Congratulations! You've just written your first program in soup!!

Explanation

So what did we just do? Let's break it down piece by piece:

func main() returns void {
  • First, the func keyword tells the compiler that we're defining a function. A function is basically a set of instructions that we want to group together so that we can tell the computer to run them in order.

  • This function, as we've specified right after the func keyword, is called main. In soup, the "main" function is a special function, because it tells the compiler that the instructions we've written inside are the very first instructions we want to run when we execute this program. Every soup file must have exactly one "main" function.

  • The () that comes right after the main are specifying the 'parameters' of the function. This can be used to pass data from one function to another. Since there is nothing between the parentheses, it means that this function has no parameters. In soup, the main function is not allowed to have any parameters, since there is no data that you could pass to it.

  • After the () we see returns void. Every function in soup can either return a value or not. This is a way to pass data back out of a function. After the returns keyword, we either specify the data type of the data that we want to return (for example, int or bool) or void to indicate that this function does not return anything. In soup, the main function is not allowed to return a value because there is nowhere to return that value to.

  • The last thing we see on the first line is {. Of course, once we define a function we need to tell it what to do. The instructions we want this function to perform when we run it are contained within a set of braces {}.

    printf("Hello, world!\n");
  • There is only one instruction we want the main function to perform, we want it to call a function. You may notice that we haven't defined a function called printf anywhere else in the file, so what function are we calling? In fact, the soup compiler comes with a set of functions built-in that we can call without defining them.

  • Okay, so we're calling a built-in function called printf, but what does it do? After the name of the function that we want to call, you'll see ("Hello, world!\n"). Inside the parentheses are 'arguments' that we are passing into the function. That may sound familiar! This built-in printf function has specified a string parameter (it's actually specified more than that but you can worry about that later...) that it will 'print' to the terminal, and by passing in the argument "Hello, world!\n", we are telling the function to print Hello, world! to the terminal.

Remember, because I was confused by this at first - you define parameters inside the definitions for functions, and you pass arguments into those functions while calling them to satisfy those parameters.

  • The last thing we see on this line is a semicolon ;. This is how we tell the compiler that we have finished specifying an instruction and are ready to move on to the next one. Every instruction in soup has to end with a semicolon, or the compiler doesn't know where one instruction ends and another begins!
}

Finally, you can see that we've now finished defining the set of instructions comprising this main file and we can close the brackets defining these instructions. Awesome!

Adding another function

Let's change up our program a little bit and practice writing a function that uses parameters and return values. Edit your helloworld.soup file like so:

func main() returns void {
    int number = 1;

    printf("number = {}\n", number);
    
    number = add_one(number);

    printf("number = {}\n", number);
}

func add_one(int number_to_add) returns int {
    return number_to_add + 1;
}

Now go back to your terminal, and once again enter the command

Now open a terminal in the same directory as your new helloworld.soup file and enter the following command:

soup helloworld.soup

And this time, the output in your terminal should look like:

number = 1
number = 2

Explanation

Okay, we've added a few new features to our program! Let's go over what we've changed.

    int number = 1;
  • First, we've defined a variable. You can think of a variable as a little container that can hold one piece of data. With this line, we've told the compiler that we want to define a variable called number which can hold an int (an integer). Including the int at the beginning of the line is like signing a little contract with the compiler saying that the little container we've called number is only allowed to hold an int, so if you try to put anything else into the container, the compiler will complain that you've voided the contract.

  • We've also told the compiler that we're going to put a value of 1 into this variable. Luckily, 1 is an int, so the compiler isn't going to complain. You don't have to put something in the variable right away, you can just define a name for it with a line like int number;

What happens if you define a variable without giving it a value? Try running a program that defines a variable without giving it a value and then prints it and see what happens!

    printf("number = {}\n", number);
  • Okay this looks familiar, we're printing something again! But what's different? This time, we're taking advantage of one of the nicest features of the built-in printf function, printing format strings. By taking advantage of format strings, you can cleverly insert the values of variables into the strings you print using a set of braces {}.

  • For each set of braces you include in a format string, you pass another argument into printf, and the extra arguments get inserted into the string in the order they appear in the function call! So in this example, the variable number is equal to 1, so a 1 gets inserted into the format string in place of the first (and in this case, only) set of braces, and you end up with number = 1 getting printed to the console. Pretty cool, right?

    number = add_one(number);
  • Now we're putting a whole new value into our number variable, and the value is coming from the result of this call to the add_one function. You can update your variables to hold new values whenever and however many times you want, but be careful, because the old value gets thrown in the garbage once you update the variable!

  • We're starting to get used to how functions work. You declare the name of the function, and then pass arguments in if there are any parameters you need to satisfy. This time, there's also data being returned back from the function. In this case, we want to store that new data somewhere, so we throw away the old value stored in number and put it there. This only works if the function we're calling actually returns a value. If it doesn't then we'd be trying to store nothing in number!

    printf("number = {}\n", number);
  • Same call to printf as before, but now that number holds the value 2, it prints number = 2 instead of number = 1.
func add_one(int number_to_add) returns int {
  • Alright, now we've reached the definition of the add_one function we called earlier.

  • This function accepts one parameter, namely an int called number_to_add. So, when we call add_one, we need to make sure we pass in one int as an argument, which we did! We should note that number_to_add is now a variable that we can use within this function, similar to but completely separate from the variable number that we passed into this function from the main function. Essentially what we've done here is taken the value stored in number and copied it into this new variable called number_to_add, which we can now use until the end of this add_one function.

  • In addition to accepting one parameter, this function also returns an int, so we need to make sure that the last instruction of this function is it returning a value (specifically an int) back to the function that called it. Let's take a look at the single instruction specified in this function:

    return number_to_add + 1;
  • So we can confirm that we have satisfied the requirements of this function, because the last instruction executed specifies that we return the value stored in the variable number_to_add, but we add 1 to that value first.

  • And that's it!

Next steps

Now that you've written and (hopefully) understand your first soup program, go forth and write some more! Reading pages like Lexical Structure, Control Flow, and Built in Functions may be a good next step. Have fun!!