 I've mentioned a few times, different places, that it would be a really good idea and something that I had planned to do a Let's Code style video series. Basically, instead of just talking about specific parts of the language or specific computer science subjects, I actually go through some, write some programs explaining how everything works and showing the whole process. This is something that's super helpful because it actually covers practical programming and really also helps show off the approach of an established programmer tackling these kinds of problems versus sort of trying to figure out a good approach on your own. So what we've got going on here, what's planned for this video is a calculator. Now we're going to begin by doing an RPN calculator, that's reverse Polish notation. Generally speaking, calculators don't do this anymore, but it is one of the simplest to implement. Basically the difference between that and the normal approach to it is that we're going to have two numbers first and then the operation, and there isn't really an order of operations thing you've got to deal with. Each operation comes before the next, so the very first operation you come to, you do regardless of the old PEMDAS stuff. Once we have that working, we'll actually go through and do the INVICS calculator as well. So obviously you need to get the input from the person so that they can actually write out the expression you want to evaluate. And for that we're going to do just expression string, let's actually put that in here so we can have something execute, get line. Now this of course doesn't do anything fancy at all. I find it best to do these very small increments, so for now we're just going to read the input and make sure that the input was actually read. So if I build this, and I'm sort of notorious for that at this point, that isn't the only language I program in, so sometimes I mix up operators depending on what I've been doing recently. Now if we run this, we'll just do 2, 3 plus, and you know it's not supposed to do anything yet other than just repeating it back. Now this isn't super useful just yet because currently this is one entire string, we can't get the individual components out of this. Now I did already, in this boilerplate, include a text package which is not a standard IDA package at all, rather it's something that I've written to kind of add in a lot of text processing facilities into IDA that weren't part of the standard library for various reasons. And in that is a split for strings. What that does is splits at whatever the specified character you tell it to, and it should follow pretty logically that splitting on spaces will definitely get the job done. So let's change this to a split string, and we want to do a split on the get line, and we'll split at the spaces. Now we won't be able to do this now, but instead we'll just make sure this works fine. So what this is going to do now is, expression now holds a split string, so basically just the string with specific divisions in it. And here you have indexers essentially asking for the specific parts of the split, so this would be the very first part which you would expect if we enter in the same thing again. Would be two, the second one would be three, and the third one would be the operation. So that's good, that's how this is supposed to work. Now we need to actually do things with this, and for that I'm going to bring in another packet. That's generic, so we're not going to be able to use that. Instead we're going to have to do this package, and it's been a while so let me just make sure that I actually initialize that correctly. No complaints, good. So what this is, stacks are a container that organizes everything in a first in, first out principle. Or is that right? No, first in, last out principle. So the very first thing you add would be at the base of the stack, you add something on top, you add something on top, and when you retrieve something it pulls it off the top so that you'd have the next thing and it pulls that off and then pulls the base off when you finally get to it. That's going to work out actually really well for this and you'll see why. But inside of the containers library that I've written there are some specialty stacks aside from just the generic stack. So for right now these are just numeric stacks, so there's like integer stack, fixed point stack, floating point stacks, and they have some additional special operations given that they're a little bit more narrow focused and that's going to be really helpful for when writing this. It's going to make this really easy to write actually. So we're going to need to go over each part of the expression. I believe we can loop over that like this, make sure that's how we can actually get the length of this. So I'm just going to build this again and it works. So then what we need to do is determine whether we're looking at a number or an operator and sets are actually going to be really useful approach to this. So let's do subtype number character is going to be 0 through 9. I believe this isn't all for now, but I don't think it complained about that so that's right. Yes, okay. I always forget what order these should actually go in because if you look on the keyboard 9 is after, well 0 is after 9, so I tend to forget whether the range would be 0 through 9 or 1 through 0, which sounds bizarre, but apparently they didn't do the sensible thing, put 0 before 9. It's not that way with superscripts, those are kind of crazy. But then we can do subtype operator and this is character as well, but we're going to have to do a predicate, we've got to double check this again. So now we can approach this by going f expression. Oh, we need the actual stack too. Let's not forget about that, so just do s of integer stack, except it's not called integer stack, it's just called stack. This is actually working quickly, this is speak, oh boy, oh because I spelled something wrong. So I spelled this one wrong. Wait because this is returning a string right now, because that's what expression is, it's different strings. What we need to do is, actually I think there's a valve shorthand for this, let's try that. There is, or rather there is, but it's ambiguous and I don't want to mess around with why it's ambiguous. Uh, no selector for pop, let's see if I can pop a 1. Oh because pop, I'm an idiot, it's not pop, it's push, pops the other one that takes it up. Oh boy, I promise I know what I'm doing, kind of, sometimes. Incompatible types, where are we looking at, this is 24, oh yeah, because we've got to do the conversion here as well, so integer value and now it should actually do the membership test. Okay, so that works, it's gonna throw an exception when it gets to the positive one though, or it's gonna get stuck in an infernal loop, clean that still. Oh boy, I, maybe I don't know what I'm doing, so we don't need that, we don't need, for something actually being an integer, I've got a better idea. So if we do, if we check, because we have these fully defined, so we can kind of just assume that it's a sort of a bad assumption, what it'll work with this, that anything not these is a number, so try to convert it to a number. Obviously if it doesn't point to being a number, then the person probably gave you malformatted input and you can handle that in an exception, which will also let us actually show up how to handle exceptions. Well, catch an exception, we're not really going to be handling it, because we're still going to terminate. So we can do if, if expression E is an operator, of course this is going to give a little bit of a trouble, because this is going to return a string, so let's do this. It's very fragile, by the way, I mean it'll work for this, but it's very fragile. So then, I actually don't remember if we can use characters in case statements, so I may have to convert this back to if else chains, so we'll do a little s add, yes, yes. So luckily, we can actually use characters in case statements, and I suppose this makes sense, because it's an enumeration, fundamentally, which means there's a set amount of things you can actually check for. We do need to handle the edge case of when others and create the exception, so no, no, no, no, raise? Yes, raise, no, no, no, I shouldn't complain about the missing case values, and it actually files. Great. So let's try running this again and seeing what happens. So two, three plus, failed. I have no idea if I recognize this as a string and so what's going on here? So you don't complain about that line though. Just make you one again and I'll see what's going on. So there is a bit of a way around this and see this is a little quirk when dealing with edda is the strings ultimately being erased are of a fixed particular size and they can't deviate from that size. That's really efficient but really bad for usability purposes so the standard strings tend to only be used when you know you can absolutely handle them otherwise what you typically want to wind up using is unbounded strings and we're going to switch to that in this instance at least in a few places where we have to. So we can convert this to an unbounded string. I believe it's going to complain about let's array type required an index component so that's here that's because the unbounded string isn't actually a tagged type which means it doesn't have an indexer it can't have an indexer implemented. So we get around that by just doing element index I really don't like that syntax but that's kind of what we got to deal with for that type. Okay so let's see what we got going on now. Okay good so it actually popped both of the values on this time around that's that's good that's kind of what we want. So then it says bad input for value now it's it didn't recognize this so let's try doing current first because now it shouldn't complain or yes it will because this is an unbounded string never mind and let's do then check to see what's going on here. Do run this and see what current is and both of these run it not build it again. I'm a freaking idiot I went through all that and completely forgot that if you notice we're doing the add operation with the stack but then immediately finishing up we're not immediately finishing up rather. So what happens is after the add on the stack happens we go to the end of the case statement which of course is the end of the if statement and then executes the rest of this which is trying to convert the add operator into an integer which it obviously is not. So what we should actually do and we can catch all of these rather simply by just doing continue... break? I don't remember maybe I just forgot to put a keyword in here so let's let's try building this and see if it complains. I had to remember what that was called I think in a surprising bit of oversight there isn't actually anything like a continue or break there so what we're going to do is just evolve loop yeah so we're going to create a label up there and some people really don't like this but that's all that's going on under the hood let's go to eval now we shouldn't run into this problem well that was interesting oh I think I know what's going on let's instead actually put this let's try actually adding the equal sign and it still goes crazy maybe that doesn't need to be a sign if we do exit when expression length we'll need to store e separately so let's do e is positive we can just change this to an infinite loop after this we're going to do this shouldn't have the same problem oh uh slightly change this let's change that is a natural we've got a zero going on here and uh let's move this up at the very beginning actually there we go okay so let me uh get a little bit cleaner output and then I'll explain what's going on here so we as before we stay we stored the expression and then we have a value here which holds whatever the current part of that expression we're looking at is as well as just the index of where we are in the expression so we have what sort of looks like an infinite loop at first it actually has an exit condition we separated this out just so there could be a little bit fighter control over what was going on but for all intents and purposes this is a four a four in loop so it does iterate over basically the entire range like sort of it does exit if the expression length is met but also if there is an equals anywhere in there it will exit on that as well but also print out the actual running total so if we were to do something like five after that you can see well let's put something that isn't the actual results let's put a hundred and see that it does list five there because the equal signifies the end of the evaluation if we remove the equal sign you can see that it does fail because it wants to try this should probably be up at the top okay that's good that doesn't do anything that's actually sort of proper behavior but that don't I have an idea can we set that to greater than the expression length perfect that's the behavior we want okay so like like I was saying this steps through so it acts basically like the four in loop just that we're doing things a little bit more manually so that we have a bit more control going on here this catches the instance where you don't have an equal sign but are at the end of the expression so that it doesn't throw an error you could actually uh change this to just an if check and then perform the equals evaluation regardless then we grab and actually store the current one we're looking at just because it makes it a little bit cleaner read but also it was sort of fickle about what exactly this was and I think that's because of how the split string actually works behind the scenes then we check for if the beginning of the element is within the operator the defined operators now this really isn't great and I'll as I mentioned before let me show you why let's put some random thing in there like a dollar sign and then it equals you can see that still evaluates and that's because it's only checking if the first part of that is an actual operator not if the thing itself is an operator so it's like I said it's a really fragile approach but it does wind up working so then we have the different mappings between the operator symbols and the actual operation on the stack now this these specifically are why I brought in the integer stack and not just a general stack of integers because while both would be able to hold integer types the integer stack since it knows it's working specifically with some variation of the integer whether uh the normal sized integer or like a long integer or short integer it knows that it can do these things to it and that's why I brought it in it's very easy to map that rather than to perform the operation and push it back out of the stack granted that's not very hard either and then we catch the case of it not being a known operator so if we instead do this what was supposed to catch that oh so what's going on here and why it didn't actually catch this I mean this shot up like a pilot but it it didn't actually you know nothing this didn't fire at all is because a dollar sign is clearly not within the operator so if you look if it's not this whole thing will never run and it never actually does this so that's a bit of a hoops but we can accept only keywords capitalized so let's just do when others it's not a great error by any means warm expression let's run this again but with the plus sign and a five now this isn't quite great yet just simply adding two numbers or subtracting two numbers or whatever you can easily do that in your head so let's actually expand this a little bit further and make sure that it works with multiple operations and that does that's that's great so if you're not familiar with reading reverse polish notation basically we have two and a three add them so that's five and then you have a five and a three and multiply five times three is 15 and this should basically be able to go out at 11 now when you get into things like this it becomes a bit harder to read but basically this wound up being evaluated to 15 and then you put a five and a one on top so that is you have 15 five and then one the mult the subtract comes and subtracts the verse two which would be the five and the one now that would be negative four because you're taking one and subtracting five from it so negative four and then you're adding 15 and negative four together which would be just 15 minus four which is 11 given the recording time I think what I'm going to do is make this into two separate videos so if you were looking forward to the more standard calculator I'm sorry that'll come next time probably the next day I've got off work but this we do have a working reverse polish notation calculator which is already pretty useful and as you can see other than me forgetting how certain things work this is actually pretty straightforward and pretty easy to implement you know there's not a whole lot of code going on here we've got 48 lines total and quite a few of these are spaces or just simple decorations the actual code looking at what 25 through 45 looking at about 20 lines of actual code this is pretty small calculate so yeah look forward to the more like infix style calculator which is a bit different and how that's actually done it's a bit trickier but it's not too bad until then have a good one