Handmade Hero Day 206 - Implementing Introspection

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
stop recording start recording hello everyone and welcome to handmade Hero the show where we code a complete game live on stream if you are somebody who pre-ordered the game and falls along with the source code today is day 206 so you wanna unpack day 205 source code into a directory that is the source code that I am starting with now and that is the source code that you would want to start with if you want to follow along with me so grab that out of the source code zip and yeah and then you can code along so where we left things the other day I was kind of thinking we were talking about this a bit and you know where we left things the other day I was talking about well we built this sort of debug stuff and we've got a little bit more stuff to do on it but I kind of wanted a way to to sort of show like I wanted a way to to sort of show entity data and we made this little thing where we could pick entities you know with the mouse we could kind of move over them all of our weird you know a little torso person or the little hero and whatever you know else is going on so we've got all that stuff and we wanted to be able to show like enemy data so maybe I could like select that entity and just see like what its state was because as we move into coding like game logic systems and stuff like that we're undoubtedly going to have a bunch of scenarios where we don't know why Andy's doing something right and we're gonna want to like be able to inspect it right and so where we left off yesterday was I kind of said well let's figure out a way to sort of dump that entity data and so what we what we did is I sort of put in what I kind of wanted to be like how that would look right I wanted to do something like this right where I sort of say hey diva you know begin the thing that we're talking about output these values and then end right and I kind of wanted that to just be you know autumn I wanted that to just be all we would have to type and then all that stuff would come out automatically in the debug UI system and you know we wouldn't have to fuss with it or anything else like that and so there's a couple things that you know we could do regarding that and I was trying to think of since this is f3 three Mathon and we wanted to kind of maybe do something a little bit self-contained for that I thought that maybe since people ask me about this all the time on handmade hero like all all all the time right about how to do like metaprogramming stuff and it's not really something we're gonna get to in handy here much I thought I thought maybe what we do for the Deaf stream is on since handmade here at any of our code heavy stream and I don't want to give people the wrong impression I figured we do a very code heavy thing and maybe I'll show you how to make this process automated so if you look and you're going here to handmade sim region for example we have a thing where we've got this sim entity and you can see looking at the sim entity right you can kind of see that it's got all of these things in it it was this is our test enemy right that we made when we were kind of getting our simulation systems up and running and all that sort of stuff and it's just got all this stuff in there and in order to output it to the debug system I have to type all this stuff in manually right and what that means is every time I change something in here I have to go change it in here as well and it's just kind of a pain right so what I thought I'd do is just show you if you didn't want to do that how would I make a very simple basic system that would add to C++ what the Standards Committee somehow in 30 years never managed to actually add even though it's like the most obvious thing you would ever add to a programming language if you ever programmed a program in your life introspection so if we wanted to introspect something I'm just going to show you how to do that I'll try to get it done in an hour it's a bit of a big thing to to sort of put out there but I'll give it a shot I know it's something people have asked about a lot and so let's just do it so in order to do that what we're going to need is we're going to need a program that we can run that will sort of you know take a look at our at our files here and output something we can use that looks kind of like this right and so that's you know we're gonna need like a little utility and in order to make a little utility that shouldn't be too much of a big deal I'll just make a thing in here which is just going to be like you know you know simple preprocessor or something like this right it's just going to be our little simple preprocessor see and again this is something that you can just feel free to use whatever you want for because like I said on handmade Hiro the proper the engine we don't use any libraries or anything like that we write everything from scratch but for this you know it does not matter so I'm totally fine with you just using anything you want to use here right so I'm gonna just say let's say you used a standard i/o or whatever to do file read and write because that way it'll work everywhere and we don't care about learning how to do that we already show it on handmade hero how to load files and whatever else right so using that I'll show you how to build the rest of the stuff from scratch and of course if you want to do this entirely from scratch yourself you can always just instead use the file routines that we use in handmade hero or something like that but I don't really want to bother reporting them out here at the moment right well I mean I guess now that I think about it well now I won't I'll just do it this way I always had this tendency to let go like well why not just not do it because we've got them already there forget about it let's write him this way it'll be fine I'll get over it it doesn't matter alright anyway so here we go with a totally standard C program so everyone's familiar with this right it's very very straightforward and if we want to use they're kind of weird file systems to load things that's actually pretty easy as well all we have to do is just open you know a file handle like you do and see here is our our simple file right whatever it is we're gonna f open it assuming that we got it we'll do something with it and then when we're done with it we'll close it right it's extremely trivial that's how that works it's not as nice as our file API where you just say read the whole file and you're done but what are you gonna do right and so for now we'll just say we're gonna Road handmade sim region which is the thing that we want to pre-process right and we'll load that in and we will go ahead and in and parse it right okay so if we wanted to do that I would prefer again to keep the library used to a minimum because you know again if it were me I would just you know be writing on top of an existing code probably so I'm gonna keep this as sort of a separate thing which works exactly like all the rest of the stuff that we did in hammer a hero where it's just going to load the entire file right so I just want a read entire file into memory and null terminate right this is a pretty handy function I always have it in my libraries whenever I'm programming and basically what this does right is you take the file name and what it's designed to do is just open the entire file read the entire file and write and and then add a null terminator at the end so that you know that the the file ends with a zero right because a lot of things and see they like to have strings that are terminated with zeros that's how you know where the end is right so here's the file contents I'm gonna look loaded up by saying read entire file into memory and they'll terminate I'm gonna pass in just handmade sim region dot H cuz that's the file that I want to parse right now and then when I do this read entire file into memory and I'll terminate what I have to do is I have to figure out the end like I figure out how big the file is right so I need a thing here where I could just say like what's the file size and there's a pretty easy way to do that and see it's a little wonky it would be nice if it was it was not as wonky but what you can do is you can use a function called F seek which moves the cursor around the file and you can say that you want to go somewhere relative to the end of the file so I'm going to do is I'm going to seek to the end of the file I can find out how big it is then right by just saying hey C runtime library tell me where you are in the file and that would actually just tell me what the actual file size of the file is right then I can just seek back to the beginning and then I can I'll have the fought in entire file right so that's the entire file size all I need to do now is load it so I can go ahead and you know I should probably also this right so what I can do just say alright I want to return this just a big like sort of chunk of memory that's just going to be the thing so now I know the final size I can just say all right the the results write equals a malloc of that file size so now I've got it and then when I F read in I'm going to F read in something of well actually every takes the buffer first just just because it does F read in that file size and and that'll be the end of it right so that's what I need to do to read the entire file into memory and let's just go ahead and check to see how that goes let's make sure that that actually makes some sense right so okay first thing I'm gonna do is add it to our build up that so here we go we already have a thing here where we compile our test asset builder right and so what I'd like to do there is just go ahead and compile this right so REM is our simple preprocessor star example here and so what I'm gonna do is just go ahead and compile a simple preprocessor dot CPP okay and now that we'll just in theory compile that for me and it looks like it did just fine and so now what I'm going to do is I'm going to actually step into it in the debugger and verify that it actually worked at all it did anything that I wanted it to do right which would be a nice change okay so I'm gonna open this up I'm gonna set it to operate in that directory where our code is right in handmade code so it can find the code which of course you know we can find that file that I want to parse I'm gonna go ahead and step into it here here we are I'm going to step in to read it entire file into memory and I'll terminate you can see me open the file it got the file just fine which is nice let's see what it thinks the file size is the file size is 33 1 3 that's 3 3 1 6 that's a totally regional number of bytes for that file we're gonna F seek to the beginning right and then we're going to malloc something of that size and F read into it and let's see if what we got was the con to the file there it is right that's the file sure sure enough right and you can see at the end here it just kind of becomes garbage the reason for that of course is that we have not actually done the null termination part but that's pretty straightforward ok so that loads the entire file into memory again really really simple so all I want to do now is I want to go ahead and allocate a little bit more space right just one more bite for that null terminator and then after we do the read in I'm just gonna say at the very end of the file put that null terminator in so now I've got terminated file right I got a null terminated the comments the file mil terminated and so now what I want to do is I want to parse this thing right I want to go through it and I want to find whatever is in there that I want to pull out now there's a problem with this and the problem with this is that it could get pretty nasty in here there could be lots of stuff and I may not want it to pay attention to all these things right I may not want it to actually pay attention to something like move speck or entity type or whatever a hit point I may not want it to parse these trucks I may not want it to do anything with these and so I need some way of annotating right mm-hmm what these guys are and so what I'm gonna do is I'm gonna go into handmade H right and up here in handmade H when we're talking actually I couldn't even put it here any platform um well yeah I'll just put it here at the top of handmade H before anything else happens I'm gonna define a little bit of markup and what I do typically for this sort of thing is I just define some macros that compile away right so what I'll do is I'll define something such as you know introspection right something like this I don't know and params some I don't know something like this right I'll just something and the key part here is that it doesn't expand to anything it's a macro that just literally vanishes right and so then you can do something like okay this struct right here I want this dark could be like a introspected struct right and maybe that's introspection done maybe just introspect right and I just say like oh the category for introspection you know is brown butter right that's I don't know why brown butter because you know it's tastier than regular blacks did like regular butter so you know what let's just say regular butter for now regular butter is pretty tasty like you get it back getting regular butter it's pretty good if the butter is good and the baguette is both good like I can just say I can see where the French are coming from on that right you know I'm American but still you know it's like I was never one of those people who called it freedom fries I guess is my point so anyway if I go ahead and compile handmade hero now you'll notice this doesn't do anything isn't create a problem for us if basic allows us to inject code that's only for our preprocessor and that's crucial it's crucial to understand how important that is that's the thing you you definitely need to know in order to start marking up that code so we've got that in there now we've got the file contents and what we're going to do now is we're going to start parsing the file now in order to start parsing the file what you want to do is you want to build a relatively traditional parser structure and the way that that works is to two phases essentially the first part of looking at the file involves what's called lexing it means breaking up the stream instead of just being a bunch of individual characters you try to in two pieces that means something a little bit more and so for example you might think about the tokens in this right here as being things like the lexicographical tokens I should have said they're called tokens that that lexing process is about binding the letters InP ro SP ECT into an identifier token like this is or or you know like a set of words right then I've got a parentheses token right which is grammatical then I've got a category token but I've got a colon then I've got a string right open quote whatever and so instead of just looking at this that's just a big bag of characters which can be a little bit daunting we've said start looking at it as a bag of tokens and that will make it a little bit easier for us to parse so the first thing we want to do is make a thing that allows us to get tokens out of the file right so let's do that here we go what we want to do is define something like a token structure we want the token structure to tell us something about where it was so weak rivalled probably want something like what the text was what you know what that what the contents of the token was we probably want us to say how long it was right so this is the length of the token right mm that's the region for it and then we're probably gonna have something like a token type right and that is what kind of token this this thing was right and so one might be an identifier like I said we got other stuff in there right we just got a bunch of things oops that was not very good not a very good cut and paste job there mr. Mira Tori if I do say so myself so we're gonna want things like you know okay we've got an identifier we've got a parenthesis you know open paren we've got you know : we've got string we've got close friend we've got semicolons in there we've got asterisks we have do we have anything else we've got open brackets right we've got open braces right things like this so we got something like this we're gonna want these tokens to come back and we're gonna want them to look like that right and so what I'd like to do is I'd like to be able to start writing code that just looks like this it's just like token taupe you know token nickels get token right and then of course I guess we should also have token end like the end of the thing right like end of file or whatever end of stream something like that right and sweet and so what I want to do is something I'm like okay let's just do a for I loop we'll go in here and we'll keep grabbing tokens until we can't grab tokens anymore so we'll do a switch on the token type right I should probably put an actual token type in there right we'll switch on the token type we'll do a case where we say okay it's gonna be one of these things right like so I guess we don't actually have to do a switch on the case quite yet we should probably just keep things a little simple at first I will just say okay give it to the end of stream we need to stop right we're gonna be done should probably do something like this - since we're inside a switch statement so we've got a bool here that's like you know parsing equals true and we'll just say well we're parsing now so then when we want to end the part you can just say the parsing is done it's over and we'll break out right so assuming that we're not hitting the end of the stream then what I want to do is I want to say what we actually found so I'll just do a thing where I say like you know what the token type was maybe and then what the string was that was there now one of the weird things about strings I don't remember there's a crazy syntax you can do to print out length strings I can't remember it you specify the width of the thing and you specify an indirect with specifier it's like the craziest thing ever but you can do it printf in direct width specification trust me this is a real thing it's kind of absurd I just want the actual def it here it is there it is that's it right there actually you can see it's that star right the wisp specification an int argument for the Argos specifies the value right so you can actually do this with strings where you're actually specifying the width to printout and the reason I care about this right is because our tokens are specified as a length and a pointer so I can't just pass right I can't just pass this because by default printf will read until the null terminator or slightly probably pass as well we'll just read till the null terminator that string and it'll just go off into no-man's land and crash or who knows what it'll do right print of different garbage until it's a zero by luck whatever so what I want to do is I want to specify an INT there I want to be able to specify that text line right I want something more like that and so I forget if I have to specify a dot for that or not so we'll find out here let's see printf string indirect string with it's something like that and it's it's just kind of crazy we could probably just sort of muddle through it as well but I'll try just present star s for now but I thinking you might have to put % dot star s this is the vagaries of C you'll have to forgive me I don't use this I don't really use printf anymore so it's it's it's not something that I have kind of at the you know at the top of my M of my brain stack of things of things to do so let's see here in a single by characters weight up to the first letter until the precision value so there it is right so it's with dot precision right is usually it's like width up precision is the way it goes so we do need that dot in there to say it's the precision value we're specifying we're specifying here with the star so read it off the stream ants a string crazytown c++ printf crazytown welcome to it okay so that's how we're gonna do our little print out thing everything should be working here except for the fact that we don't have a get token thing and so what I want to do here is I want to have a thing like called tokenizer or something to store the state of this just so we know where we're at something like this right it might store some other things later I don't know but I just want a thing that we pass around for state so what we're gonna do is say that we have a tokenizer the tokenizer is is just going to be initialized to have just that app pointer pointing at our file contents like so and then we're gonna say go ahead get a token from this tokenizer thingy that I've created and that get token it just expected to do whatever it needs to do right okay so here we go how do we actually do that well at first of all we probably want to do some basic things that tokenizer x' or and i guess this is technically lexing i guess at this point right we want to do something that lexer is typically do we want to eat up any white space because typically in programming languages like the one we're using here white space dust does not matter right so what we want to do is do something like hmm you know eat a white space or something like this where we just say like before we do anything else get rid of any white space that's in there because we just simply don't want it right and so here's the art eat all white space we have our tokenizer and what we will simply do is go okay while the tokenizer at you know while this this app thing while we look at what it is equal to and what it's equal to you know is white space so we can do that pretty easily in fact we could even make a little query for it like this we could say well that's white space we want to go ahead and advance it right so we're just literally moving past any white space that's in there again really trivial probably for anyone to write as well that is white space function pretty straightforward that just takes some care whatever it is right I'll guess we'll call it C and it just is going to return this result and that C equals basically any of the whitespace stuff that we know of right so if it's that if it's a space if it's a tab or something like this if it's a new line right then we want to say that it's whitespace right so that's it so while that's happening we're gonna advance by the whitespace then what we're gonna do is take a look at see what character we're actually on and then we're gonna do something with that character right and so let's just see what all the stuff is that I said we were gonna purse and let's grab it like so and so I'll just say okay if the token is an identifier oh that's right we don't know that yet that's not what I want to do it all we want a way to determine yeah all right brain getting a little brained it's true in order to figure out if something is an identifier that's gonna be a bit of a catch-all because that's like anything could really be identifier so really what we want to do is focus on these guys first right if we see an open paren we pretty much know what we're dealing with here right our token dot type equals an open paren and we're done right so I think basically you know these guys should be really really straightforward in fact like it even I could probably compress this down with something really straightforward something that looks like this right and so here's the other ones we've got here we've got closed paren that's going to be this guy we've got semicolon that's going to be this dude right here right we've got asterisk that's gonna do this guy yeah we've got Open bracket right OOP that was not where that goes not where that goes not at all so Open bracket close bracket I don't know why those braces got got plurals on them they were a little bit too too ready to go should be only open brace all right open brace close brace so there's that go right so that would just determine what we were looking at when we're looking at something relatively straightforward I forgot the : one there there we go okay so that's you know all we really need for all of these guys but then we've got the string and the identifier one and in fact you know what I'll do is I'll move those guys down here so we can kind of see like you know here's our string you know here's our sort of our simple guys versus complex guys right and similarly at the end we also kind of know in fact we could even do it here where we say you know if if we see the null terminator right as part of the character as well that's going to be token end of stream right so yeah so all we need to do here is just assume that our result token right let's just assume that the result tokens text length is one and we'll assume that the tokens text is where we are at and that will just make it so that all of these this the multiplicity of cases here is just a trivial assignment of the type and then we return and we're done right and so then all we have to do is start implementing these more complicated cases here like let's say we see one of these quotes right or something like that or let's say we get some other thing here and we're gonna treat it as an identifier right okay so what we want to do now is we want to say okay if we get a string we just want to read through the entire string till we get to the next like quote right that's all we really want to be able to do so in order to do that all we would say is okay you know while you know we're just gonna advance the tokenizer we're just gonna say okay skip over that quote because we don't want the quote to actually come out in the string value right so skip over that quote and then let's say that the tokens text is equal to where we're at now then we just want to keep going until we see a close quote so we basically want to say you know while tokenizer at is not equal to a closing quote and we also want to make sure that it's not the null terminator because we might at the end it might just be an invalid you know program whatever while these are happening we just want to keep you know we want to keep advancing so in here we want to do you know a simple advance like that now since this is C and C allows you to escape with a backslash things like the quote inside a string we probably also want to just do a little bit something extra here and say that if the tokenizer at happens to be a backspace like it just happens to be right then we will actually advance the tokenizer past the next character whatever it is right so we'd say something like if the token eyes are at zero equals the backslash and you know the tokenizer at one the next character is not equal to the null terminator so that it's not like the end of the stream then at that point we'll just say skip skip two characters right otherwise we only skip one and so that allows us to keep parity with C so if there's quotes and strings if someone quoted out if someone that quoted a quote ate a double quotation we won't end the string prematurely and fall out of phase with the C way of parsing things right so okay so we've got that and now we just need a way to parse identifiers right and so inside our processing for identifiers you know we've got this default case we pretty much got two things we might want to look at right one is is this thing alphanumeric right so so basically is this thing like is it an isn't an alphabetical character I guess what I'm saying so is alphabetical if it is then it could be the start of an identifier right and so whatever the tokenizer app value is if that's alphabetical then I want a person identifier here right otherwise if it's a number right or is is numeric I should say something like that then we might want to parse the number okay and that's really all we would need to do here we haven't implemented those yet so we're gonna have to think about this but there's one other thing we need to do here which is if we end up in a case where we see a slash we have a little more work to do right because there's comments in C code and we want to bypass the comments so we actually also have one more thing that has nothing to do with the training a token it's just about skipping over dead space right and for that matter we could put that in the whitespace eater as well right so in the thing that does eat all what whitespace I hope how far were you guys gonna let me get in that I can't really blame because I'm not looking at the chat in the thing that does eat all whitespace we also might want to do sucking up of comments because comments are basically considered whitespace and we don't want them right so while the thing is whitespace right we want to advance but actually probably what we want to do here is something a little more sort of drawed where we do something like okay keep going for a while if it's whitespace right then we skip over it else if it's one of these guys right let's say it's that then we want to potentially parse a comment right so we would do something like okay like this right so that's gonna be a comment right that's gonna be a C style comment VAR c style comment and furthermore we also have the same situation happened here where we might have something that opens I'm sorry that pass was a C++ style comment I misspoke and here is the C style comment right something like that okay so assuming that none of those is true then we're done no more white space to be eaten right so now we've got our work cut out for us we've got all the stuff in there for the most part for some reason I insist on typing tokenizer dot even those tokenizer arrow I will rectify that with a little search and replace and done and then we just have a bunch of things here that aren't actually implemented yet right so let's do parse the seesaw comment all all that needs to do right is it just needs to go until it sees star slash so we can assume in cure I guess we'll just say that the tokenizer at right we just skip over in either case we skip over that part right and I think actually now that I think about it we can probably we I don't even know why I bothered putting these in here they're pretty straightforward so I wonder if maybe I should just write them in line write all that all that they actually do is you know while tokenizer at you know is not equal to and and tokenize radicals are so while it's not a an end-of-line right and i could actually do something to even here that's like is end of line kind of a thing I could just even have a function that tells me that right and something like that right that makes sense so yeah if I want to do something like that I can just do like while not is end of line on the tokenizer at zero let's just go ahead and advance right so that just eats everything till the end of the line and of course I also again want to check to make sure we're not null so you know while there is a character to read and it's not the end of the line then keep going and just eat it eat it all up right the same exact thing will happen here right and and that's like after we skip over this guy we just keep going and say okay while we do not hit hmm sort of that the stop the the the closing part right so while we don't get basically this guy that makes sense so we're basically saying while there's a character to read and the I should say this way while I nice is a little boolean logic for you there while that whole thing is not true right while the the star slash is not exactly what comes next right then we can advance ahead right when we break out of that if the thing that we're looking at is the star right then we are going to want to advance past it because that means that we didn't run out of characters and we want to skip the star in the slash which we ended on right okay so that's really it for those guys now we just have a few more note we got to fix the errant plural there now we just have to do our sort of more complicated person here where we're going to sort of try to pull out these other sorts of things so we've got two things we've got is alpha so you want something that tells us whether this is an alphabetical character we also want something that's going to tell us you know is it numeric is it gonna be a new number thing and for right now I think we can probably just just use Falls for that because we'll get to that maybe a little bit later on right how exactly we'd want to do that so this is you know to do kc once we do numbers do this right although I suppose you know we can probably guess if we wanted to that's like you know if C is greater than equal to 0 and C is less than or equal to 9 then it's a digit right if that makes sense and there's probably like a dot that would also be another one in there and like the F and an O X right so there's probably some things but for now we'll just use that one and we'll go a little bit further when we need when we actually need to write these alphas really simple that's just going to check to see whether were in the alphabetic range of the ASCII character set right so here is that that's for lowercase and we can do that or uppercase okay so that you know test those two right that's whether or not South with your merit we can now get that sort of information back and so we just need now to be able to do the two parses parse number we don't really need yet because we don't care about that so really what we could do here is just sort of like I said wait a second on this one and we'll kind of look at that one a little bit later when we actually care about it so for now all we'll do is when we get to a default thing we'll probably just say like okay we don't know what this token actually was so maybe we just say at that point we throw it out right so we just say like okay this token dot type equals token unknown or something like that right so there's just some kind of thing like this token okay and what we'll do here is we'll also say that you know in the case where the token is unknown right we could also do something where we skip those right so we won't print those that will only print tokens that we know for now so that seems hopefully pretty basic all that seems good parse identifiers actually now I think about it it's really not that complicated either I mean all we really have to do is say okay the token starts where it took where it started and so we just need to do the lengths we should also do that for our string by the way here at the end of our string when we do all of our string parsing we picked up what the string text was right but we need to to set the length which we didn't do and we also need to set the type right which is the token string so we need to say this a string and then we also need to set the end of it right so at the end of all of this once the thing has gotten to the end what we want to do is say okay at this point we should be sitting on the actual you know the actual stopping point so we should be able to say whatever the distance is between the app function right and whatever that place we started and where we began right which we saved sorry the place that we're at now and the place that we began if we subtract the two of them we should get the length of the token right so with the first part of the string the first character string we know where that was that's token text the last character string we're sitting on it now right and it's that closing quote so we track those two what we're done but we also want to do is skip that closing quote because we're still sitting on it right so assuming that we actually found the closing quote and it's not that we hit the null terminator and like you know it was an unclothed string or something assuming we hit that closing quote then we want to skip the closing quote make sense okay so that's really pretty basic and again this stuff I could I guess I'll expand this detector be a size feel though we're never gonna be parsing files that are that big I'll say it's a size T for now very good okay so press identifier oops mistake thank you compiler for catching that um so for parsing this guy an identifier is just a collection of alpha and numeric things plus the ability to have an underscore so really all we're gonna do here for this is we're just gonna say while tokenizer at zero you know while that whatever that is is alpha or it could be is numeric or it's an underscore right and I think I'm gonna say is number because now we're actually using that for reals right so I think I actually want to call this is number because that's a little clearer then that's the things we can put in identifiers in our code that's all the things we ever use for them so while that's the case we'll go ahead and advance the tokenizer at at the end of this again we will just have that tokenizer at be specifying the link this way so it's wherever it started versus where it ended so I think that's everything at the end we return the token that we got and we continue right so that's pretty straightforward so let's see what we've got here let's go ahead and step through this we probably have a bunch of bugs that's a lot of code to type in at once like I said I went pretty fast as I wanted to kind of compress it down just because it's something that we're kind of doing a weird stream not like we normally do but anyway here's our tokenizer in action our lexer basically the first part of the tokenizing so here we are looking at this stuff so we're gonna have some things we don't understand like that pound we don't know what that is so we should go in here and and get an unknown token which we did let's see now this token should be an identifier basically we're gonna go in here to eat all whitespace we're gonna look at this thing and it's none of these right so we're gonna exit out of there we're gonna start by assuming that we have a token length of 1 here is the token text right we're starts on that pound Oh aha we do have a bug already token unknown when it sets that needs to skip over right these guys need to skip over the token app so none of these guys I guess that's sort of the thing these guys don't skip over that first that first guy right and that's a that's a problem so how do we want to deal with that right how do we want to how do we want to make it so that these can be convenient you know because I can do this but it seems a little bit annoying for me to kind of have do it every time like that I don't know doesn't that seem like kind of a pain maybe it's not a pain but for these hand-coded guys you know I mean you could always back it up I suppose we could do something ridiculous right we could do something like this where we say you know by default go go past it or something like this so we do like care C equals tokenizer at wow this could be a real bad idea but we could do something like that so that all of these work and then this guy of course this would just work because he already wanted to advance by the quote so that's fine so it's really this guy who needs to know what's going on here right so this guy says something like all right assuming that C was alpha right then we're gonna run through these guys while it's still their work you know we're gonna kind of add to it and I think the rest of this sort of works so let's let's just see how that goes right okay so let's see what we get here let's get back our first token there's our token it's a token unknown it's one length of one it's that pound right there which is what we expect so that's good let's now see what the next token is the Lexx token is token of length two but that's specified as unknown as well I think that's just because again that was just me forgetting in here we've got to set the token type right - token identifier but that should have that shoulda parsed okay right in fact I should probably do that look right at the top when we do them for the most part just so I can see that I actually do it there okay all right so there we go there's our token unknown now we should get a token identifier and hey we did it's text length too so we're going to print it out to the console and there's the output right from it oh well actually know the outputs over here because it's a console app so there's an eleven there was our if and so as we run I think we'll probably be okay so I can probably just actually run this guy on handmade code now and actually get it to to work right so there it is right and you can already see that just from this you can see that we're kind of already parsing what we need parce right do you see how this has already kind of lined up into what we need right I mean you saw how simple that was what I just typed in and now we've got a really straightforward kind of a situation here for being able to pull these guys out right so we're starting we're starting to get there how much time you got left we have 15 minutes left I don't know if we'll quite make it in time but we'll see all right so let's start by trying to identify that part that we actually wanted to grab there so as we're doing this this tokenizing what I want to do is I want to go ahead into handmade sim region here and take a look that is the key that we're looking for we're looking for this introspect and we want to go ahead and grab that out right so what I want to do here is go okay if I hit a token identifier okay so I've seen an identifier what I want to do is that you want to know is the identifier introspect right so I want to do is say if token equals something like this right introspect something like this then I want to parse an introspection right you know or int respectable something like that right so I'm at a person is respectable I need to pass the tokenizer to it and that's how we know we're gonna start parsing one of these special structures something that you know has been marked up especially for us so we know that it's something that we want to use in in our you know in our pre pass or whatever right so there's the tokenizing that's gonna happen there and and what I'll do is I'll just suppress this printf for the default now and what I'll do here is I'll just printf our introspective all at this point right mobile start will start in there okay so what I need first of all is I need that token equals to be a thing because we haven't written that yet and so here what I want to do is I want to make an inline that returns a bool and what it does is it takes whatever the token is you know whatever that token was and then it takes a care star that's like you know the string the mat and it just sees whether or not it matches right and so what it's going to do is it's going to say okay I know that the token is a certain length right I know that it's text length so I'm going to go through and say okay from zero to token length like so I want to make sure that match of that index and token text of that index I want to make sure they're equal right so if they're not equal it's over it's false right make sense and similarly I want to make sure that if the match index right I should actually say also here just do this up first so if the match of index if that equals zero so it's the null right the null terminator that kind of thing right it's just zero if the match index is zero or they don't match then return false otherwise the result of this function is just going to be whether I'm gonna need this index on time mmm is going to be whether or not we got to the end of match so I'm gonna need something well you know what I can do let's just do this right so as we go through this we just say okay if you know start at start at something like that right then advance them in fact I can't even put that right in here so just run along match check it against the thing when we get to the end if star at happens to be equal to the null terminator we know we got they both ended at the same time and so we know that we can say that that it was actually true otherwise it's false so that's just a little like string compare thing that we have there and we can go ahead and test it so let me go ahead and come down here right and so let's go ahead and see what happens if I step in here and now the token itself right is obviously going to be equal to something totally not that it's like if right and so our app is pokey beginning here we go to through the index the index is zero these two won't match so we should return or not Oh idiot because it's an eye alright so actually they will match on the first one then they won't match on the second one and it should return false so off it goes but then eventually we should get to one that returns true if we done it correctly but I don't know if we actually did doesn't look like we did because we never actually got to a token that equals that so now we got to go and actually see let's double check here when we get to a token I guess what I'll do is I'll say if I just want to be able to plug this code if token text zero equals I and token text 1 equals n write something like this and so this way I can just I'll only have to look at the ones that actually have some thing related to introspect and then we'll you know go from there ok so here we go let's see if we've gotten to a token that's relevant there it is that's a token we want so we hit getting the token equals we take a look at what's happening with our matching so now let's see where we're at and at and where we aren't index is 0 so we advance through these guys we're advancing through as we would expect right and what happened there what is the token length one two three four five six seven eight nine ten but that yeah and the token like this ten but our start at what happened there Oh oh that's just a typo well we almost did it right we almost did it right that's pretty funny all right there we go so now hopefully we're back in business there we go so here we are parsing and respectable so now we have to do is actually do some gathering of the stuff from there and let's see if we can do that right okay so what we want to do in parse it's respectable is we want to just like read out exactly what this thing is right so we know that we've gotten a token for introspect so now we want to do is we want to basically like get the parenthetical phrase there so I'm gonna kind of do this very straightforwardly because again we only have about ten minutes left so I'm going to do sort of the base version and then maybe Monday since if people found this useful or interesting I'll show how to do a little bit better right but it would look something like this right you know something like if require token tokenizer token open paren write something like that then what we'd want to do is just kind of I guess I don't care about this very much but what we well yeah let's just do it right then we do something like okay we do parse purse introspection params something like that right and we could almost even do this where we didn't actually have to do that but you know we should do it anyway right and here you know we do something like a printf you know f2 standard error we'd say something like error missing parentheses right and we'd want to kind of do a better error for these schemes can I say I'm doing but I'm doing this sort of bare minimum thing here rather than anything fancy so okay we require the token we do parse introspection for Rams assuming that we actually get those out right then we would do something where we go OK token token equals get token and this is probably like struct token right so we go or or you know type token like what's the thing we're going to do let's see so we do get token on the tokenizer right if token equals you know struct then we know we're parsing a struct so we do like parse struct otherwise we do an error introspection is only supported or a structs right now sadface right something like this okay so if we do that we need these two things right we need static void parsons inspection params and there's our tokenizer and all i'm going to do there is I'm just gonna do like token I'm just gonna have this eat everything for now right and so I'm just gonna do token equals get token and I'm gonna say like you know if token dot type equals token close friend right or token type equals token and a stream then it's over otherwise we eat everything so eventually we'll like parse the actual things in there but for now we won't bother if we see a struct will parse obstruct and what we do to parse a struct is going to be something like okay we need to get the name first right that's the name of our struct then we need to parse all the members of the struct well actually then we need to do a require token on an open brace right we need open brace and then we need to come in to sit here and wait till we find a closed brace right so we need to sit here and go like you know member token equals get token tokenizer and then what we do is say like okay we look at that member token if the member token type equals token close brace then we're done right and that's that's basically what we're that's basically what we're after otherwise we'd parse it five-minute warning getting close so you know we get the token the member token and then what we do is we do something like parse member and pass it that member so can that we got and that would do whatever it's gonna do right so not that complicated you can kind of see how this is going and we'll see if we can get most of it done in the next five minutes oops that supposed to be tokenizer so we just need the choir token parser parse member takes the member token this is like the type token probably number type so that's really all we need to look at and inside the parse member basically we can also do the same thing for this one right now we can just eat till the semicolon right and that should do it okay so let's just quickly write require token all require token is again very very straightforward is instead of doing a get token what require token does is it gets the token from the screen stream and then sets the results of the you know that it's going to return to be whether or not that token type equaled the desired type right and it's just so that's just shorthand it's just an easy way to say the only thing I allow your is this so I just require it right so there we go and let's see so there we go I'm gonna just quick run that it's not gonna do anything right but I just want to make sure we don't crash or loop or hang or anything like that so now we want to do is you want to get this out putting something reasonable so okay so we have our little weird magical printf thing here that prints out you know sort of token sizes so what I want to do here is when we get to our introspection struct for every member I just want to print out right this you could see what the code was I was trying to do I want to print this out so what I'm gonna do here is I'm gonna do something where we can print out like this debug value thing or something like that just for just for show right that's all we're gonna do all I want to do just to make sure that we've got something resembling anything is I'm gonna make this parse number thing do that mm-hmm okay so here we go inside parse number I have my number type token and as you can see in here right we've got you know these are the member types that kind of come down the side here you can see them but sometimes they've got a pointer like this old chunk thing here it's got a pointer right and then sometimes like that like array stuff at the end of them too right but for now we can kind of ignore some of that so what I could say here is all right I got my member type token I get this token here I want to see what type this token is right and I'm going to switch to the parsing method here again so I can switch on whatever the type is so when I get the token out of this it could be one of two different things really well it could be its it could be an asterisk right and it could be an identifier those are the two things that were there right so what I want to do is say okay I got my remember type token and right now we're only handling things where this is just a regular identifier on the phone that's the first thing and then I want to say like okay is it an asterisk around in a fryer that comes next in fact probably actually what I would want to do here say if the token type equals an asterisk then this thing is a pointer right we don't really care about that yet but we'll just say like is pointer equals true or something like that so you know it's a pointer and then get the next token all right something like that so if it's a pointer it's a pointer and we could even say that that's sort of gonna be a thing you know we could even move that out here so we just say like okay well parsing token get token if the token is an asterisk we'll say it's a pointer something like that any I guess now I think about it the original ways probably better for the shorthand way we probably want to do this a little bit a little bit differently if we were gonna have more than a few seconds to implement it hmm but assuming its identifier now we have all the information that we actually need to print this thing out right and we I guess we also want to still have these two cases here where if it's the semicolon or if it's the end of the stream we would stop parsing right oh man okay hold on one second I just want to put this printf in here there we go so this would just be like that we had here before I just want to put debug value in here where I print out that name and that's going to be again this token assuming is asterisk it's going to be setting its pointer so nice identifier I'm gonna assume that it's the name for now that's not really the way that we want to do it because it's not it doesn't parse everything that we might want to parse and see but it's pretty close for now so there we go let's go ahead and compile that oops and that's not supposed to do break that's supposed to be a oops oh my goodness I know what that does parsing equals pulse all right so let's run this and see what happens Hey look so this as you can see is pretty much exactly what we wanted to do so if we come back here to handmade CPP you can see that we now something that we were doing manually and we automated it right and there's a bunch of things we could do now to this if we wanted to we probably don't want to output this this way we've got a lot of cooler stuff we could do with this if we wanted to but there you go so that's introspection in an hour there's some more stuff you know we'd want to flesh this out a little bit more but yeah one hours worth of code you got an introspective going and you can take it pretty far from there if you want to staying on schedule here I want to try and keep because this is the dev stream Athan I don't want to be our normal cells where we go nuts and potentially go off schedule or do whatever with the Q&A so I'm keeping on time 30 minutes of QA and then coming up after me also is going to be the salt and sanctuary stream so if you're interested in that game and you're on the dev stream it's on that's coming so all right let's go ahead the Q&A if you could please if you want to ask a question please put Q colon in front of it and I'd be happy to go over anything I know like I said we kind of wanted to do something weird so I picked that one because people always ask me about how to do it on the stream so now you know and like you saw it's real real easy you know you can make a much better one that what I've done if you spend more than 30 60 minutes and aren't talking the whole time but you get the idea q : I see no Q Cullen's somebody posts a Q : for me to answer if there is one if not we can all just chill out Paul Smith it seems like you are doing recursive descent parsing is that how you would describe it yes absolutely I probably should mention that so basically there's a number of ways you can write parsers and and you know since there aren't I don't see a lot of Q colons here I'll just you know I'll start with like just a little bit of explanation here oops how do I get my little uh how do I get my little interface back here where's the way where did the little where did the little interface go oh there it is okay so here we are de 206 and I'll just mention briefly so for parsing yeah what I wrote is definitely considered a recursive descent parser and you know to be fair actually what I wrote is just a descent parser we didn't actually use the recursion yet now we would if we had done you know if we were doing spending two hours on it and getting a little more of the type parsing in there we would have but what you saw me do is just to get it going a little faster I used a lot of these while parsing blocks so technically the way this works you wouldn't do it this way the reason it's called a recursive descent parser at the recursive part is because normally what you do is you look at what you got if you got an asterisk you then call parse member again on whatever comes next and you build like a tree that way so I just did it I did it kind of in a more fast and loose way but like you know if Monday we go back if people want to see me expanded a little if Monday we go back you would see a little more of the recursion that you didn't see because I was just kind of short handing it so I made things in loops that really traditionally in a traditional cursive descent parser sorry I didn't pack enough water for this train so my voice is going yeah it can just be a smooth jazz stream from now on um so yes so if you take a look at that ass that like that Astor's think that would have been a case where recursion would have happened the traditional recursion and and that's how that would have worked right and I can even I can even show you kind of more like what that would look like you know you could imagine in fact you know you could just imagine with this if you took out the the wild parsing thing so you know I'll just I'll give you the the more sort of complete example right so assuming that we did it the more recursive way what we would do is something more like this where we say okay just get the token whatever the token type is we'll handle it if it's an asterisk I just want to do parse number again right something like this and so that's exactly the same thing right but it's a little like you know it's a little cleaner it's a little nicer potentially and so if I you know if I wasn't kind of being a little more compressed there if this was a regular hammer measures were like let's spend this week on metaprogramming I probably would have thought it through a little more and had something a little bit more that way right so yeah if you take a look at how this works do that and that's right so that's like a recursive sort of thing where you we kind of go down like that and so now if we if we run it you seem to get the same output but you know I just I was just kind of like I said I was playing it pretty fast and loose so this is a little bit nicer and you know that's probably the one I would leave in there as well so you know that's just better that's where the recursive part of recursive descent comes in so just just want to clear that up okay so recursive descent parser that's where the recursive part is is this that you assume that instead of like doing while loops to parse things that can have multiple components you use recursion and the stack to do descent is because we're going down the stack and up right so you can see that we start at like the outermost shell and we look at what the tokens are there and when we get a token we say okay descend one level down the stack and look at it a little bit more carefully decide what you want to do with it there look at it again go a little more carefully right we just send down so you kind of like you're winnowing down the options as you go until you finally decide what it is you actually parsed right so that's a very traditional type of handwritten parser right so typically if you're writing a person by hand like we just did you write it this way they're very nice because they're very flexible you could do anything you want with them you can put an ad hoc code to do anything you need to do they're very understandable it was probably I'm guessing pretty easy even though I went for a faster that for you to understand what was happening you didn't just see like a big bunch of gobbledygook where it's like a what's happening but there are other types of parsers right there's like shift reduce parser x' and things like this and oftentimes these other kinds of parsers they use like rolling arrays and stacks and things and they have jump tables that are pre you know made on stuff and what they're typically for is there for generation so typically what happens is if you write a parser generator so like yak or bison if you've ever heard of these tools they will spit out sometimes other types of parsers which are machine they look like sort of machine table driven kinds of things they're not really so much for writing by hand although you could they're just not as human natural I found what you'd first write you know and so yes what we what we did on this dream was a recursive descent parser it's a parser that's very traditional in that way very traditional hand-drawn top-down recursive descent parser one token look-ahead kind of thing very very straightforward sudonym 73 can you please satisfy my C standard anal retention by accepting /v and /f as white space mm-hmm because I like pseudonym 73 quite a bit I am more than happy to honor that request for you that is no problem although to be honest I don't know is there anything in particular I have to do like there's nobody all end of lines on all three platforms are /m r / r right is to see ever let you end the line with anything like that doesn't tell me I've never used one of those so Guerry Johansson asks have you have you an opinion OpenCL see I I've never really used OpenCL and I definitely don't know what OpenCL see is but but yeah so I'm sorry I know I don't have it I don't know what OpenCL see is how would you handle errors if you were deep in the recursion is checking return to us everywhere the best way so error handling usually what you do it depends on the circumstance but usually the reason why error handling is so bad and compares is because it is a bit tricky and so usually what I do is when I encounter an error I typically do something like I try to put it enough logic into the parser for my needs but you can go more nuts with it and usually what I do is I have an error token - you know so you'd have like token error that people can like pass off the chain and I also have a tokenizer on the tokenizer you call error and put errors into the tokenizer that it like stacks up that's usually the sort of thing I do I showed a slate can you explain what introspection is sure so actually technically there's different words there's introspection and there's reflection and there's different levels at which these things happen but basically what we're talking about is in most programming languages you typically have well obviously a programming language is all about specifying structure of some kind right you expressing the structure of data you're expressing the structure of code you're expressing all of these sort of structures right and they could be literal structures I can see it's a struct it's literally just a collection of data it could be a function write a series of things to execute with loops and whatever and the compiler for your language knows what these things are it has to because it has to then turn that into working code right and so the the key thing to understand is that structure actually has a semantics form somewhere inside the compiler while it's compiling the code now languages that have a clue languages that were made by people who know what they're doing that's not even true languages that just any language should have this but C++ doesn't because it's just not maintained by people who know what they're doing so C++ lacks a very crucial feature that most modern languages have and that feature is the ability to look at those structures from within the code right so the structures that the compiler knows about inherently you can get them during the compilation phase and do things with them that allow you to work with your code in very powerful ways so for example here is our entity structure that we were playing around with on handmade hero right it has these fields in it I would like to print them out there is no way in C or C++ to say tell me all the members of the cemento t structure so that I can print them out you can do it in other languages you can do it in JavaScript even you know you can you can do it in all these languages C let's can't do it and that basic ability is called introspection it's also sometimes called reflection which is if you have the ability I think to like work to actually do more complicated operations than that it's it's sort of a it's it's a thing that it's a it's a more stringent requirement I think on top of it but point being whatever you call it what we're talking about here on the stream is the ability to do that sealless else doesn't have it so what I showed on tonight's dream is how to implement it right how to put it back in there because the c-plus welcome is obviously never gonna get around to it so you need to write and so that's what we wrote this is just a very simple little preprocessor then we can run on our code and you know here is that struct right that's the manatees truck and you can see when I go ahead and run this right if I could I'll bring it up on here here's my sim region code and here's we ran our preprocessor and you can see it printed out the members right old junk storage index right that sort of stuff and we've got some bugs here like this guy right you can kind of see even what happened oh you know what I introduced a bug actually you can see that we did it correctly before but when I did that code just now for the recursive descent spoke a little too soon so if you look at that code for the recursive descent there is sort of a nasty problem with it which is if you look at these two guys this one handled the semicolon end of stream thing it would properly eat till the semicolon but a recursive descent thing didn't so really until we do that I guess I can't quite switch to that and I'll put in I didn't mean to undue pseudonym 73's thing here yeah so it would not have worked properly the way that we were doing it before oops that's I'm in the wrong place okay so yeah our original one worked worked better I knew I must have had a reason for doing that that way but anyway so you can see that we printed them out here we got old chunk storage index updatable type Flags PDP distance limit collision facing direction t Bob D AB style hit point max hit point soared walkable dim and welcome al height right and so basically what we did there is add that introspection back in so now inside our preprocessor we can do whatever we want with those things right and that's what that's exactly what we needed and what C++ doesn't give us ah let's see do you well it just says do you if John does metaprogramming for his language I assume you mean do you know if John does Matt a program for a night do you mean does does it have a program the answer is yes he showed actually for the first time the meta programming features like Wednesday night just this past Wednesday he showed for the first time some of some meta programming features he's added so I think it probably will be pretty good language for meta programming based on how it's going so far certainly much better than C++ which doesn't support meta program at all insofar as regretting errors again would this be a place for exceptions would actually be useful no exceptions are never useful I've literally never found a single programming problem where exceptions are better than not exceptions you know your mileage may vary if you like him you like him but I I literally cannot tell you a single time when I've ever thought that exceptions were the right way to program something in my whole life there was a time when I thought that exceptions were a good idea because that's what I've been told but if I look back at all the programming that I've ever done with my current brain I literally can't think of a single time I would ever say to use them they are never good I literally don't know of a single time I would use them everywhere now that we have the preprocessor do you plan to make more use of it going forward in handmade hero I don't know I mean will at least output the debug will output the annotation right it'll only take us a day to switch that to an annotator so we might as well we've got it right Hogan long who is John and what language talking about talking about Jonathan Blow designer of braid and the witness and the lead programmer on both of those products as well he's writing a new programming language called jei which is actually pretty far along and it's quite nice you can take a look at his YouTube channel Jonathan Blow just search for Jonathan Blow you too and you can you could find it about that Cu voucher I'm writing a parcel looks pretty similar to this but it runs on multi gigabyte files which takes a while any common approaches to use simony multi-threading to speed up text parsing seems more difficult since the characters aren't independent in the way pixels are you know there's a lot of ways to speed up parsing certainly so I suspect that probably you could do some interesting things there but honestly I have never done parsing for bigger than just my codebase and even like just this method of doing it is always like many orders of magnitude faster than the compiler actually compiles it so I've never had to optimize one of these ever they're always the fastest part of the pipeline for me because like Microsoft C compiler is so slow that pretty much nothing I ever do it becomes a compilation bottleneck so if you're talking about more like you said multi gigabyte files I do appreciate the fact that that would necessitate some serious thought there but I just don't know I just don't have the experience with it to know like what you know I guess what I'm saying is in my head I can sort of think of things like okay how would I start to approach it right but they're just fully speculative and and I just I just don't know I would have to actually go tackle that program prime myself to have it really in the opinion because it doesn't it's just not something I ever had to think about to Sophos the stream makes me feel like an extremely inferior and incompetent programmer do you approve of this not really I mean I guess I would just have to ask the question like you know hopefully you know if you look at what I did there it's not that complicated right like there's not that many moving parts - it's very simple it's just something that takes a look at characters in a stream and make some simple decisions about it right and so you know if you look at that and go wow he like did that really fast or something uh you know I've been programming for like for like oh my god 32 years I've been forgiving for 32 years I've written you know five six parsers seven parsers something like this mm-hmm so one of the reasons that was so fast it's cuz I just already know basically how it works right and so it's just it's just very like second nature for me to type that out and so you know I would kind of discount that part of it so what I would focus on it's like say can you understand what I did if you just spend some time look at it and practice a little bit and if the answer is yes then you're as good a programmer as I am the only difference is you haven't written six of these right and a lot of times that's a big part of the difference right the reason that somebody looks like a good programmer when they're programming is because they just have a lot of experience you know the first couple times I tried to parse tough it was a disaster I didn't even know about tokenizing I'd never read a book on parsing and it was like they're awful they were like oh he's scared for things and I remember the first time someone like told me hmm you should like do a lexer you should have a thing that breaks my tokens it's like this huge eye-opener for me right so I feel like yeah like don't get discouraged when you see someone who's been programming forever like who's an ancient like old crotchety cane like and I'm not even making that up like I am on crutches right now like here are my crutches I I crushed over to this to do this Deb stream and I will crutch out to the other room when I'm done when you see someone who's been programming so long if they're on crutches at this point and they're old and invalid don't look at that and go like oh I can't program that well it's like well duh but that doesn't mean you won't thirty years from now right it's just a question of programming every day and like actually doing the practice you just get better and eventually you can program quickly how does meta programming change your workflow can you talk about incorporating generated code with the regular C files yes so the way they typically works is exactly what you just saw basically what we do is we'll take this and we'll have it start to output some things that are meant to be read as standing C structures so for example what I would probably do right is instead of outputting this debug value thing what I would said output is something like you know here is the the name you know the the field of the thing or whatever as a string right and and I'd wrap that in something like this right and so this is more what we'd start to do and now you can sort of see like okay this starts to be something we could just insert in a C file right and so then maybe we're like okay well now you know we want to insert the sin of C file we've got this press truck thing we get the name token out all right so now it just becomes like let's go ahead and print out what destruct is right so we'll say something like hmm carest are members of right and then we just output that that thing like members of blah brackets equals and just going to go ahead and give you what the idea is here right right and so you can start to see how this starts to become like actual C code and so then you would just do something you'd imagine you have like member definition or something right and then up here when we when we actually output this thing we would also do like some kind of type field or something like this so you know member type token would be here as well so it would be something like you know type underscore or percent dot star s member type token text length member type token text and it's not going to work quite right yet but you can kind of see so this starts to now right be kind of close to something we could just read in code and know exactly what our struct layout looked like right so basically we do is we just take that we output that to a C file and we compile that C file in with the rest of our C files now we have introspection data the kind of the C++ spec should have been giving us for the past two decades and wasn't right so it's just about getting that in there in a way we can use so all right so that's that's pretty much all the time I've got I don't think I got any more time for questions so I'm just going to go ahead and wrap up because if you're watching the dev stream Athan then you are going to want to it's gonna roll over here in five minutes to the Salt sanctuary I believe is the the next the next step on the stream so I'm just going to go ahead and save this out and close down and say thank you for joining me to this special edition of handmade hero it's been a pleasure coding with you as always I hope that satisfied some people's desire to see how meta programming how you sort of start to get that working that is the basics of it like I said you saw it can happen in an hour and of course now it's in the hand made your a code base so if you're somebody who wants to play around with it hand me here org you can always pre-order the game and it comes with the full source code so you can just download the source code and play around with it and see how that works if you are still a little confused about how the meta partner stuff works and maybe we'll do some more of it on handmade hero in future streams as well if people feel like they just want to see like a little bit more of how that sort of thing works so that's about it until next time oh yeah if you want to catch the stream live again please do remember also that we have a little tweet bot here so if you want to see the schedule you can see the schedule so hand made here org you can just go there and there's a little tweet bot it'll tweet out the schedule at you and you can see that it's just like you know every week it'll it has a little thing here which will say like here's what the stream times are gonna be and then every day it just tweets out a little thing that tells you what the time is that day if you're wondering so it's a pretty handy little guy that's about it for me if you're watching the dev stream of thumb it's twitch.tv slash dev stream of thumb like I said it goes I think for 24 hours I think it started a few hours ago so it's going all night and it'll go all day tomorrow as well there's a bunch of devs on there doing stuff so definitely check that out if you're someone who just came for the handmade hero and hasn't had enough live coding for one evening you've got more so you can go ahead and switch over to that and I guess I'll just keep talking until 10 p.m. because I don't know when they'll actually switch over the stream I hopefully at 10 p.m. exactly so there we go and I guess I'll take this opportunity also to say thank you to everyone for tuning in as always all the handmade hero guys it's great to see you here every day it makes it a lot less lonely to code knowing that there are so many people who come to visit and yeah I hope you enjoyed that metaprogramming it was the thing I had been thinking all week about what I thought we should probably do and I was like well we could do you know people had mentioned me we do some lighting stuff and me you do some animation stuff and I think those were all good ideas but what I thought at the end of the day is I was like well you know handmade hero is what it is you know it's a stream about actual like very serious programming and it's about the programming and so I felt like people who are watching for the Destry Mathon I didn't want to do something that would give them the wrong idea about the sorts of things that we do here like we do very low level stuff that's that's what we're about we're not about like you know making a game we're about learning to program a game and those are two very different things right and so I thought that something like that would be a good example it's a self-contained thing I knew I could do it pretty quickly I've written so many metaprogramming things in my life I knew it was something that you know it was we had a chance again done an hour as luck would have it we did that was not afford to have a conclusion and certainly we you know it was right down to the wire but as you saw you know that's kind of the sort of thing that I feel like typifies handmade hero is that kind of programming and so I thought that would be a good example and also something that people who watch am a hero every day would also be entertained by because I know that a lot of people have asked for that in the past and you know that they would want to see that so that's it thanks everyone for joining me and I hopefully everyone will will stay tuned for some of those dead students on things let me know how that is I'll probably go switch over and take a little bit of a look at it myself so take it easy everyone and have fun coding I'll see you guys back here on Monday
Info
Channel: Molly Rocket
Views: 14,220
Rating: undefined out of 5
Keywords: Handmade Hero
Id: 1IwYEJsvdcs
Channel Id: undefined
Length: 90min 15sec (5415 seconds)
Published: Fri Oct 16 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.