 So, let me try and pull up the, I don't know if that's now the, I don't know if I do have it. Well, okay wait, I have my A, if it just loads. Okay, so I was asked yesterday by one of my friends if this would return an error, or if it would make them all the same type, and I said all the same type. I, yeah, so this means, right? So this means you're defining a new type A that's a B, defining a new type C that's a D, which are all implicit types. And then you have a variable X which is type A, a variable Y which is type C. So then when you see this, so what do you know about X and Y? They all become the same type. They all become the same type, and also Z also become the same type. But what type is that? B, because it was first. Yes, B because it's first, exactly. Okay. No, I have to cancel. Okay. If you need me with me, we can schedule something, because otherwise I can do answer questions now. I'm just thinking, the TA can attest to this, and my project deleted itself in front of his eyes. So I had to restart twice yesterday. Did you submit? I hadn't submitted anything at that point, but it literally was right in front of his eyes that it deleted itself. He can attest to that. But I sent him an email. Yeah, I sent him and me an email. On the project, Type Tracking Air, it says that there was one condition, it says that the condition must be Boolean. I wonder what can it trigger that in the condition part? Yes, condition. So, some type of this basic form is the list? Yeah, yes, this one. I mean, am I allowed to kind of like, in the condition, you know, it has a left-file, and left-file and it has a relu. Does the relu must be kind of like one of those things, or can be like one of those kind of like, the condition, right? So you have a... So there's a relu. Am I allowed the relu to be like something rather than like less, or can it be to kind of like pass, minus? Relational operator. It's a string. You have to follow the grammar, right? The question is, can that ever occur in this grammar? No. So I kind of like, what can ever trigger that condition must be Boolean and the things? Yes, so basically, if you see a condition, right? It's an ID, the type of this ID must be a Boolean type. If it's a relational operator, then you don't have to do anything because you know a relational operator will always return a Boolean. But for a relational operator, the rule holds that the less inside must be the same type as the right-hand type. So you have to check for that. So I'm like, pretty much using like four different lists, like an implicit type list, an explicit type list, implicit variable list, and explicit variable list. Is that like an okay to go about doing it? Get close, man. By the time you're done with the type section, you should have collected all the explicit types and implicit types. I honestly don't know what I'm missing. Not necessarily. Because once you parse the variables, you may have new implicit types. In the body? Oh, yeah, that's right. Also in the body, right? Because when you see a new implicit variable and implicit variable has a brand new and implicit type that you never saw before. So when you're done with the type section and variable section, you should have collected all the explicit and implicit types. No, that's what I'm saying. Oh, even types can be in the body? Not explicitly. But let's see. You know if I'm going to die. So here, what's the type of W in this example? Well, I mean, isn't that an implicit variable? Yeah, it's an implicit variable. So what's the type of an implicit variable? Whatever on the right-hand side is the... Kind of, but I wouldn't think of it like that because you're forcing it to be something that it may not be, right? Because what if you have two implicit variables? I have W equals foo, and I haven't defined foo, right? So I have two implicit variables. So that has no type? That has no type? W has no type? It has a new implicit type. Unknown type. Yes, it has a new unknown type. So you can think about it's exactly the same as if you declared here a variable W with some new type that hasn't been seen and it's implicit. So W has an unknown type. But there's no way to store that information. Yeah, it's just a new implicit type. You can just give it a new name that you don't have a name for anything else. But we would never print that, would we? No, to test. Correct. That's weird. The other key differences is that when you don't know, just because this type is not unknown and the next type is not unknown does not mean that both the same type of unknown are different unknowns. So couldn't you just use null or something? You don't need to actually hold it. Oh, but you need a type. A type for it, because what if later on it turns out that W is actually an int? I made that up. I made that up. The type of W is actually an int. So sort of going on with this. So would you recommend, like, when you create an implicit variable, not only would you create a new implicit variable entering the symbol table, you would also create a separate implicit variable type? Yes. Well, how does that work? You have to create a new one that you have to reference to, but you could have infinite of these very close with infinite different types of... Yeah, just so you can have infinite number of types and infinite number of variables. It's not infinite. But you would have to... Okay, so... You can... Like, when you're parsing this type table, right? You're creating a table and adding types to it dynamically, right? Right, like as I go through I'm adding to the list. So you have a function to add a text to your table. Right. So why can't you do that here? You just give it your own internal name for this type. I did actually... So I type it into the three-sign tables in my code? Yeah. I don't actually ever use two of them. Probably should be done. But keeping those four lists that I was... That's cool that I could just add... That's really funny. Because I've been doing that with the explicit so far and that's worth it, all right? Yeah. It's the first time you see, you know, an implicit type. You can just add it into... Yeah, there's plenty of ways to do it. I mean, you can do it like that. You could do it one giant list of types. I mean, I would keep the types and the variables separate. Yeah. But you could have just, like, a symbol list. Yeah. But have each element of that list which structly has all the metadata, right? Yeah. With the name of it, what's the... Is it a variable? Is it a type? Is it implicit? Is it explicit? This type is kind of... Okay, cool. Thank you guys for sharing. Perfect. So I'm getting close to the end. Would you be willing to give me just some extra test cases? Because I've just... I've been hammering the test cases for hours yesterday. I just can't get anything extra. So I sent you my code because I would show you my laptop, but my laptop's dead. Oh. So would you be willing to test some test cases on my code and see if I'm... Right now, no. Because we're recording. Yeah. Fair enough. It's only that I don't want to pull my email and put it on you. I understand. I understand. I actually think it was questions from students. So if you'd be willing... If you could test my code against some test cases... What test cases are you failing? Maybe I can... I'm passing all the syntax, all the 1 dots and 2 dots. I'm passing 19 out of 24 on the semantics. I'm pretty sure my errors are probably coming from not printing out the table at the end properly. I'm sure that's it. And I'm passing 3 out of 5 on the extra credit. Okay. So... I'm not sure why I'm not passing all of 5 on the... I'm assuming all 5 on the extra credit are just checking for whether that the variable in the specific shape is an int. So I have a check for if it's a consonant, that that's good. If it's a variable, that's... that is of type int, and that's good. If it's an unknown type, then it assigns that type to int. I mean, stuff like that. But I'm only going to pass 35. So it means that the thing inside the case statement is an int, right? And then... Are you an int? Too many cases. I know. It also means this is an integer. So if that's... If it's not foo in this case, if it's 10, then it will pass. If it's 1.2, it won't pass because that's real. If foo is an unknown type, it assigns that unknown type to int. And then if foo is not an integer type, it throws an error. Okay. So I think that's... And also in the cases, can we do... Can we have cases? That causes syntax errors. I'm pretty sure it says it has to be a number. Yeah. But then you're also correctly type-checking the body, too, because that's the other thing you have to do. That should just be... I'm doing it all in the parsing, so it should just automatically catch that. Assuming you're properly parsing the body. Like, that's what I mean. If you're properly doing that, then yes. I think I am, I think. I could throw a switch statement inside a switch statement and see what happens. I would try that. Okay. So you're passing all these? Yeah. Supposedly these. I'm passing 19 out of 24 on those. Oh, let me know. For whatever reason when I was tapping it on my phone, I accidentally hit send, so the first email has nothing in it, and then the second email. Okay. Sorry, usually I don't ask teachers about code, but so I'm passing the syntax tests, but my while statement isn't actually working. Okay. I have no clue why I passed the test and no clue why it's not working. I would go with the not working thing is a problem first. Yeah, yeah. So I have, I made this simple file, right? To check a while, and this would be the left operand, that would be the right operand. So in my parsing, I'm like, because I couldn't check if this was this to get the 1.4 error. I couldn't, I couldn't match x, I couldn't match x to this type because I would throw an error because you're not supposed to use it as a variable, right? And I'm like, why is it doing this? So when I went through, in my condition, my condition pars function, when I call the second primary, so like when I do primary and then get the left operand is x, and then I check if it's a relational operator, and then I call primary again. It switches the left operand to the new primary call. Lubica, Lubica. Okay. So the syntax error is just making sure you're not, you're actually parsing it correctly in the sense that you throw a syntax error and create a syntax error, right? Oh, okay. You're properly, I see. This is a correct test case, syntax-wise. Okay. So it passes, which means it passes. Okay, so it works differently as well for if I put a number, then an ID. It works differently. And then when I call... Let me do something super weird going on. Okay. So left operand primary, t-type, greater than, less than, less than, not equal, less than q. Relational operator, good. Primary again. Okay. It's got to be somewhere in the primary. Yeah. I figured out it's when you call getToken that it weirds it out. Like I called getToken. Oh, okay. Go to primary. What is primary return? It returns a primary node. Okay. It's exactly the problem we talked about in class. Okay, so look at this. Where is this variable at your prim node? Where is that allocated at? What kind of allocation is this? I don't understand. From the allocation stuff we learned in class. What type of allocation? You're declaring a variable called prim. Right. Yeah. Where is this pointer declared? It's declared. You're allocating it here. Yeah. Okay. Why don't you do it here? Well, I did it there and then I changed it here because I'm like maybe this is causing it so I was switching, trying to see. All right. Okay, good. Just making sure. Okay, we got the ID. Okay. This is the classic problem. Right? You're declaring prim ID with token. But every time you call get token, token changes. Yeah, but. You need to call string dupe to get a new string. Why does, so token. The lexer constantly changes token. Token is just a. So it's not a static reference is what you're saying? It's like. No, it is a static reference. And the lexer uses token to contain the current token. You must find the same problem in project two and project three. I just, I don't understand because when you get the token, you set it equal to, this is, this is not a changing string. But does it always like, does it always check if token changes and changes it accordingly? Like. Check if token changes. Go up to the lexer. Look for do a control f search for token. It's going to find a lot of results. Yep. Go back up. Sorry. You go P dupe. That didn't do it. No, that would, you want to undo that. Okay. Yeah. Now search for token again. Backwards P. P. I did press P and it just inserted a slash. Oh, that's weird. Okay. I don't know what's going on. Sorry. Okay. Then search for token. All right. So see, look at here. Scan number, right? Yeah. So it's setting token. So it's changing token here in this scan number. Right. Okay. Keep going. I keep going. Scan ID or keyword. Yeah. Here, same thing. It's changing token. Right. So every time. Okay. That's definitely a problem. Okay. Keep going. Go, go. Go. Look at, dammit. Okay. Go back up until we see that token. Boom. Right there. What is that doing? It's setting ID equal to a string that is the same as token. Exactly. It needs to create a new string because token is constantly changing, right? But what I don't understand. Every time you call get token, it uses the same token buffer. Right. Why? It's a pointer. Yeah. Oh. It uses a pointer to this buffer. That's why it's a pointer. Okay. Okay. Okay. That makes sense. So you need to call string dupe which will create, allocate new memory for you and give it there. So every time you're trying to assign to token, you need to call string dupe. Okay. Okay. And I saw you had that also in the switch statement too. So you want to make sure you do that there too. Okay. If you do that, your problem will go away. Ah. It was so frustrating. I couldn't. I couldn't figure it out. So frustrating is a very good attack. Thank you for your help. Yeah, yeah. Any more questions? I mean generally.