lemme learn ya a thing or two.

wow, you're still here!

Welcome back! Today we'll focus on the language part itself for our own Lisp dialect. If you haven't already, refer to the first part of this tutorial series to get started.


improving our buffer stuff

I'll admit it, I was a bit lazy with the last part of the tutorial. Before beginning any of the language, let's improve our buffer stuff, and include a readline function (those using Windows don't have to do this).




Before we begin, your code should look something along the lines of the below image:



Perfect. Let's continue.


laying out the law.

Before we get into any programming, we should plan out what we want our dialect to do, how to act, and what happens if something is incorrectly programmed. For this, let's analyze how computers interpret our written code, as we would.


In C, say you wrote the following pseudocode:

#define goodgrief printf("lmao\n")



Let's break this down..


  1. You're telling the computer (technically the compiler) that for every instance of the string "goodgrief", to replace it with "printf("lmao\n")"
    1a. You're telling the computer to print "lmao" with a new line to the output.
  2. In the event that the numerical value of "fucksgiven" were to be equal to that of zero, to continue running the program. If it doesn't equal zero, then the program with abort by default.
  3. In the event that the above numerical value of "fucksgiven" is true, then the program will print out whatever "goodgrief" is, and return as "sucessfully run".


This is fine and all, but this is only true if we allow it to be true. In the C programming language, the above is a given, but in our Lisp dialect, it's not default. We need to define the rules for our language in order for it to make any sense at all.


but what about math?

If we want any functionality of our Lisp dialect, we'll need to create the ability to do math. Like many other functional languages, we'll be implementing RPN (Reverse Polish Notation) as our primary way to do math.


that sounds like a polish joke.

Yes, it does. However, it's (in my opinion) the best math format out there. Allow me to show some examples:


4 + 7 + 14 + 5     would be     + 4 7 14 5

5 * ( 7 + 39 )       would be     * 5 ( + 7 39 )

( 23 + 1 ) / ( 9 + 5 )     would be      / ( + 23 1 ) ( + 9 5 )


Pretty weird at first, but you'll eventually like it.


We should also define our expressions. Here's the basics for what we'll implement for those using our dialect:


.                                                                                      Any character IS required.

x                                                                                     "x" IS required.

[xyzcum]                                                                         Any character within the [ ] IS required.

[x-m]                                                                               Any character within the x-m range IS required.

x?                                                                                   "x" IS NOT required.

x*                                                                                    At least zero of "x" IS required.

x+                                                                                   At least one of "x" IS required.

$                                                                                     Input end IS required.

^                                                                                     Input start IS required.


As this is the way I learned how to do this, we'll be going off of an extremely useful library for defining our own expressions and such - mpc. Please install it before beginning.


can we finally get started?



Go ahead and place mpc.h as a local header.



Let's get to work on our parsers now. Feel free to name these as you want, but I'll be using what I like. We're going to be adding to our prompt code on this one.



Before our system("clear");, let's add our math function.



We should also add a sort of maid system to delete parsers when we're through with them. Luckily, mpc does that for us!



Excellent. Actually, we went a bit ahead of ourselves here. We should probably program how to handle user input, so we have something to clean up! Let's again utilize mpc to make this happen.



Hopefully, your code ends up looking something like this (likely sans emojis):



If not, debug as necessary. Now, let's go ahead and compile & run.



Alright, so we know it compiles with no errors. Let's try a bit of RPN and put it to the test! Go ahead and input the following:



You got an error, right? Of course you didn't. But it isn't working right for some reason. It keeps clearing after pressing "Enter".


Figure out what it is yet? Keep trying.


In the event you either found it and fixed the problem, or gave up and want an easy out like the little spoon-fed bitch you are, scroll down for the solution.



















































Delete the line with system("clear");. By continuing to clear the buffer, the loop can't give a clean output. Run again, and with RPN, same as last.



Neat! It's not clean by any stretch of the imagination, but it's functional! Let's try inputting something that isn't math.



Cool, it worked! Well, it didn't give us a proper output, but that means it worked! We didn't program whatever you typed in yet, but we will in the next part! Stay tuned for tomorrow!




tutorials on whatever, daily. doesn't have to be tech-related, but it mostly is.