Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 765 766 [767] 768 769 ... 795

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 818185 times)

strainer

  • Bay Watcher
  • Goatherd
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11490 on: September 17, 2019, 02:24:45 pm »

Thanks, I count myself lucky if I get away with being called "etymological picky". That idea of a stack sounds like a well designed heap management system. I do also have a load of files lying around called blast.html/js/... short for blastosphere which connects in with the origins of matrix.

Also seems like "const and let" should clearly have been name "let and mut" but at this stage Ive got the feeling I should let it be.
Logged
Klok the Kloker !

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #11491 on: September 17, 2019, 03:19:19 pm »

It's partially historical. Lots of browsers were already supporting const as an unofficial extension to the language, so they just formalised it as a part of the language.

JavaScript is up there with C++ in terms of being shackled with a lot of language features that exist for historical reasons.

Even it's name is a result of historical weirdness, the language having nothing in common with Java.
Logged

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11492 on: September 17, 2019, 08:36:31 pm »

I'm really frustrated with this C++ program.

So I built my program by debugging in the terminal, I've never done this before. I ran into a problem I can't solve by inserting print statements in my code, so I fell back on an IDE and set up my project in Netbeans. The problem is, my program is intended to be run in the terminal, and I pass the input by redirecting it in:
Code: [Select]
./a.out << input.txt
When I'm in Netbeans though, I can't do that. I don't want to refactor my code to work with an fstream object. Please, for the love of god, how can I use an IDE with breakpoints without having to refactor my code? In the meantime I guess I'll try and learn to use breakpoints in the terminal, ugh...

I can't even see how intractable my problem is yet, because it's not creating any output (which is why printf() failed me). I'll leave a zip with my code in it here after I remove all the human names from it, I wouldn't mind some help getting it to output correctly. It's a recursive descent parser
« Last Edit: September 17, 2019, 09:08:13 pm by Parsely »
Logged

bloop_bleep

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11493 on: September 17, 2019, 09:38:54 pm »

Eclipse with C++ is a bit heavy and a bit invasive, but the upside of that is you can specify a run configuration that takes standard input from a file, and a bazillion other options.
Logged
Quote from: KittyTac
The closest thing Bay12 has to a flamewar is an argument over philosophy that slowly transitioned to an argument about quantum mechanics.
Quote from: thefriendlyhacker
The trick is to only make predictions semi-seriously.  That way, I don't have a 98% failure rate. I have a 98% sarcasm rate.

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11494 on: September 18, 2019, 01:27:59 am »

So, I worked out the earlier issue I described. I was using "<<" instead of "<" to redirect input. I'm dummy brain. I even did this correctly earlier to test the parser. Anyway, that let me make a bunch of progress and now I'm getting actual output! Still problems though

I've already tested the parser and it consumed all the input with no errors so I'm confident that that works. The new problem is that the statements are being executed in reverse order. This is my first time handling a vector in C++ and that's the structure the statements are stored in so that probably has something to do with it. I sense something is wrong with the way I'm inserting statements into the vector and not with my for loop. Once I fix that, I think I have a problem with the way I'm accessing or storing the operands/constants/left hand side variable, this is the most intimidating issue. I'm also vaguely suspicious of the memory vector where my constants and variable values are stored


Code: (sample basic input) [Select]
MAIN
X = 1;
Y = X;
OUTPUT X;
OUTPUT Y;
1 2 3 18 19
Code: (expected output) [Select]
1 1
Code: (sample basic input) [Select]
MAIN
INPUT X;
INPUT Y;
X = X + Y;
Y = X+Y;
OUTPUT X;
OUTPUT Y;
3 7 18 19
Code: (expected output) [Select]
10 17
The INPUT statements consume one integer token, from left to right, and assign it. Any extra input is discarded

I don't know EBNF notation, but here's the grammar reference that I used to write the parser.
Spoiler: Grammar (click to show/hide)


Yet to be implemented is the procedure and do statement functions. Once I can execute a statement list properly those ones follow pretty cleanly since all you're doing is storing a statement list for each procedure, and executing it when it's invoked. Same deal with do except you loop
« Last Edit: September 19, 2019, 12:10:30 am by Parsely »
Logged

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11495 on: September 18, 2019, 10:58:02 am »

Line 195. You're pushing to the front of the vector each time, meaning that the last statement is the first element of the vector. You then read it from beginning to end, which is, hence, in reverse order.
Thanks, just changed push_front to push_back and that fixed that. So now we're executing in the right order. Two problems now though:
- I tested with the input below, it returns 8 when we expect 5. Also, the lines 520-523 commented "TEST STATEMENT" in the switch statement aren't doing what I expect them to and printing out the integer values at those locations in the memory vector, what gives? Am I accessing the vector incorrectly, or am I messing up when I assign them values? It doesn't always print the strings either... Also, reading that statement now it doesn't really make sense what I'm trying to print, I should print the actual character symbol representing the LHS and not the value of the LHS, but still
Code: (input returns 8, expected 5) [Select]
MAIN
INPUT w;
x = w+1;
y = w+2;
z = x+y;
OUTPUT z;
1 4 17

- I tested that first sample input up above and it looks like my code has a bug somewhere in parseExpr(), it throws a syntax error while it's trying to consume "X = 1;", I didn't detect this error before because I was only testing with statements that have two operands
« Last Edit: September 18, 2019, 11:01:53 am by Parsely »
Logged

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11496 on: September 18, 2019, 11:32:30 am »

General rule of thumb is that you can never have enough debug prints. Dump the entire set of variables you're storing after each instruction is executed, then look for discrepancies.

How I would do this is to break parsing up using an "eval" function that can be called recursively.

How this would work at the base case, is that if eval sees just a number, it returns that number. If it sees just a variable name, it looks up the variable and returns its numerical value.

At the next level, if eval see "(" it looks ahead for the (matching) ")" symbol, then calls eval again on the inner contents. Doing it this way, recursively, means that you get accurate brackets handling for free, basically.

I think you'd need two passes for the last bit, one pass resolves all variable names (probably by calling eval again, because that reduces redundant code), * and / operations and a final pass to resolve all + and - operations. Since everything that's inside brackets is already dealt with by splitting out that bit of the string and calling "eval" again for it, you don't need to worry about the complexity of brackets.

It's a little more work, but this is how you might make a simple general expression parser that's more flexible.
« Last Edit: September 18, 2019, 12:03:59 pm by Reelya »
Logged

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11497 on: September 18, 2019, 12:02:26 pm »

General rule of thumb is that you can never have enough debug prints. Dump the entire set of variables you're storing after each instruction is executed, then look for discrepancies.

I described my issues doing that:
Also, the lines 520-523 commented "TEST STATEMENT" in the switch statement aren't doing what I expect them to and printing out the integer values at those locations in the memory vector, what gives? Am I accessing the vector incorrectly, or am I messing up when I assign them values? It doesn't always print the strings either... Also, reading that statement now it doesn't really make sense what I'm trying to print, I should print the actual character symbol representing the LHS and not the value of the LHS, but still


This is where the action is for the aforementioned input, since this is where we're actually executing an addition statement. In the code below, the first three lines are where I'm printing out. I changed this a little from what is in the .rar because my debug statements didn't make sense semantically, this represents what I'm running now
Code: [Select]
cout << "LHS before execution = " + mem_vec[pc.LHS]; // TEST STATEMENT
cout << "\n"; // TEST STATEMENT
cout << "expect LHS = " + mem_vec[pc.op1]; // TEST STATEMENT
cout << " + " + mem_vec[pc.op2]; // TEST STATEMENT
cout << "\n"; // TEST STATEMENT
mem_vec[pc.LHS] = mem_vec[pc.op1] + mem_vec[pc.op2]; // Execute addition
cout << "LHS after execution = " + mem_vec[pc.LHS]; // TEST STATEMENT

But like I said, this doesn't print as expected! Some of the strings before the mem_vec references are missing characters, and in some places no integer is printed at all! I feel like this is an issue converting the integers to string or something, maybe I should do the conversion explicitly first? I'll screenshot my output once I have a chance so you can see what I mean

Edit: OK you edited in a bunch of stuff while I was typing. Need a minute to read

Edit2: I'm at the stage where I've actually already consumed all of the input and I've stored all of the tokens and ALL the syntax checks out perfectly (small exception where an expression only has one operand as in "X = 5" but "X = 5 + X" is stored fine with no syntax error). My parser is able to check the grammar perfectly. The problem I'm having is, these statements are arithmetic statements, and once I parse them I am storing them as a struct so I can execute them like a program, this is where my problem is happening
« Last Edit: September 18, 2019, 12:08:09 pm by Parsely »
Logged

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11498 on: September 18, 2019, 12:10:05 pm »

What I edited in is unrelated to your current problem, it's just a different approach to parsing to the one you're using.

But my point about the debugs prints, is that you're not printing ALL your variables each time anything happens. You're just printing what you expect to change. If it's not acting as expected, you're probably doing something unexpected. Doing a complete memory dump of ALL variables, even ones that you don't expect to be affected may trigger an "aha" moment or give you leads towards where the error is. Do a literal entire "stack dump" after literally every little change, and see where something unexpected occurs. Just write a function which does a "core dump" of your entire system, and do one of those after each instruction, see where things go off the rails. For example, input 1 to "w", then dump all variables, then set "X=W+0", then dump all variables again. And so on, with different inputs and amounts.

EDIT: Note how you said bits of some strings are missing. That may indicate that your tokenizer isn't actually breaking the tokens at the right places, so it's something to check. Also, cout should always correctly output ints as ints, since it uses operator overloading to always get the correct conversion, thanks to OO. The only issue could be if you're storing something as a string and you didn't properly parse it in the first place.
« Last Edit: September 18, 2019, 12:22:47 pm by Reelya »
Logged

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11499 on: September 18, 2019, 01:00:33 pm »

But the parts of strings that are missing when I print are the literals I'm writing in the cout statement

Code: (input) [Select]
cout << "LHS before execution = " + mem_vec[pc.LHS]; // TEST STATEMENT
cout << "\n"; // TEST STATEMENT
cout << "expect LHS = " + mem_vec[pc.op1]; // TEST STATEMENT
cout << " + " + mem_vec[pc.op2]; // TEST STATEMENT
cout << "\n"; // TEST STATEMENT
mem_vec[pc.LHS] = mem_vec[pc.op1] + mem_vec[pc.op2]; // Execute addition
cout << "LHS after execution = " + mem_vec[pc.LHS]; // TEST STATEMENT
cout << "\n\n"; // TEST STATEMENT

Output:


That doesn't have anything to do with my parsing. I'm not storing any string in my vector, mem_vec only stores the integer values of the constants and variables in the expressions. The lexer is working just fine

The core dump function is a good point though, I see what you mean, I'll implement that later if I can just get my mem_vec to actually output integers

E: OK, I think something is wrong when I'm setting the values for LHS, op1, and op2, that's the only thing that would explain what's going on here, and I would have known that sooner if I had just printed out everything

E2: OK, the problem is definitely in parseExpr() and lookup(). When I print the lexeme (string value of the token) in parseExpr() it's giving me what I expect, but the int value is empty when I try to get that after calling lookup() on that token, so I think lookup() is failing to store and/or retrieve the address correctly. Lookup() is supposed to store new algebraic symbols in an unordered map in a symbol-address pair, where the address is the index to a corresponding spot in the memory vector so I can reserve a position to store that symbol's value there. Constants are also stored in the mem_vec  by lookup() when they're encountered in an expression. Lookup() searches for the constant in the mem_vec and the symbol in the unordered map before it tries to store them.

E3: Fixed this bug :sunglasses:

Quote
- I tested that first sample input up above and it looks like my code has a bug somewhere in parseExpr(), it throws a syntax error while it's trying to consume "X = 1;", I didn't detect this error before because I was only testing with statements that have two operands
« Last Edit: September 18, 2019, 02:34:59 pm by Parsely »
Logged

strainer

  • Bay Watcher
  • Goatherd
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11500 on: September 18, 2019, 03:37:40 pm »

mem_vec's values are clearly not converting to string properly for cout.

Parsely, I do wonder at how you get people diving into your zip files and following the fast shifting trains of thought and focus, with no obvious recognition of the extra time and attention spent by those do unpack things and make suggestions. Mere mortals have to carefully compose their problem and make it accessible in code snippets or a repo, and to somewhat limit inquiries to a economical number of pressing issues. But I guess this is not stack-overflow and you may in practice be hosting some kind of adventure game :P
Logged
Klok the Kloker !

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11501 on: September 18, 2019, 03:51:00 pm »

mem_vec's values are clearly not converting to string properly for cout.
OK, I'll look into this soon.

E: mem_vec is a vector of integers, so shouldn't cout automatically convert the integer to a string, or else fail to compile?
E2: Using to_string() made my debug statements work, thanks! I guess mixing literals when using cout is not a good idea, and I should always convert them explicitly

Parsely, I do wonder at how you get people diving into your zip files and following the fast shifting trains of thought and focus, with no obvious recognition of the extra time and attention spent by those do unpack things and make suggestions. Mere mortals have to carefully compose their problem and make it accessible in code snippets or a repo, and to somewhat limit inquiries to a economical number of pressing issues. But I guess this is not stack-overflow and you may in practice be hosting some kind of adventure game :P
Sorry, I hear you. No one owes me anything, I don't expect anyone to understand my code easily, and therefore I do really appreciate the amount of effort that Reelya and Ispil have put into helping me out with this problem, it's very helpful and I value that. I'll try to be more clear and concise in the future.
« Last Edit: September 18, 2019, 04:38:54 pm by Parsely »
Logged

strainer

  • Bay Watcher
  • Goatherd
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11502 on: September 18, 2019, 04:51:37 pm »

Quote
mem_vec is a vector of integers, so shouldn't cout automatically convert the integer to a string, or else fail to compile?
As much as I can recall, string and char conversions in c++ are not always what they seem and possibility cout itself has its own idiosyncracies, eg. maybe it can't tell they are ints so I would try casting to int or things like "std::to_string((int)mem_vec[key])" until something works. I do often find c++ like an old text based adventure game trying find the one true way of saying "poke open trapdoor with broom handle" :)
Logged
Klok the Kloker !

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11503 on: September 18, 2019, 04:59:42 pm »

Lol yeah, I agree on that one. :) I noticed I actually had some compiler errors when trying to do things like:
Code: [Select]
cout << "some string literal" + integer1 + "some other string literal"Let me try and reproduce the error just for funsies

Fakeedit:
There it is
Logged

bloop_bleep

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11504 on: September 18, 2019, 05:35:48 pm »

Yah, make one a string first before concatenating.
Logged
Quote from: KittyTac
The closest thing Bay12 has to a flamewar is an argument over philosophy that slowly transitioned to an argument about quantum mechanics.
Quote from: thefriendlyhacker
The trick is to only make predictions semi-seriously.  That way, I don't have a 98% failure rate. I have a 98% sarcasm rate.
Pages: 1 ... 765 766 [767] 768 769 ... 795