I’m trying to build my own compiler with C++ for my own basic programming language. In the beginning, I was following a series of YouTube videos from the channel Pixeled, but after a while I decided to stop watching them and try to continue the project on my own. Currently all I have is variable declaration (only of integers), binary operations (sum, subtraction, division, multiplication and comparisons), if statements, and (not functioning) variable reassignment.
When trying to implement it, everything started not going as expected.
My current logic is:
-
If I encounter a variable during parsing, that was already instantiated, followed by an equal sign (=), it must be reassignment.
-
I create a new “Statement” node to my AST specific to variable reassignment.
-
I move the stack pointer to “one position” above the position of the said variable in the stack (8 bytes because I’m working with 64-bit x86).
-
I generate the code for the expression related to the reassignment.
I move the stack pointer one position above because my code generation for the expression (let’s suppose here it is just an integer, to simply the question) moves the desired value to rax
and then pushes the value stored in rax
into the stack. So, moving the stack pointer prior to this assures that the new value is pushed into the right position.
But, I abstracted the push
instruction into a function that also increments the value of my compiler variable stack_size
. So, even though I’m not changing the number of elements in the stack with this strategy, it still changes the value of the variable.
I obviously thought of not incrementing the stack_size
variable when executing a push
, but my code generation for whenever I find an integer (being a variable assignment, variable initialization, term inside the exit()
function, etc) is the same: I always do this strategy of moving the value into rax
and then executing a push
.
I also thought of adding a parameter to some code generation functions related to variable reassignment, so that, for example, if I’m dealing with this process, I don’t increment the stack_size
variable. But, first of all, I thought of it not being a “smart/correct/elegant” solution, because I would have to add this optional parameter to the statement generation function, that also calls the expression generation function, that calls the term generation function, that finally calls the push
function. And, obviously, I can’t write the assembly code myself whenever I find a variable reassignment statement, because I can’t guarantee that the expression on the right of the equal (=) sign will be an integer, a binary expression, another variable, etc, and therefore I need to have this sequence of function calls.
I don’t know If I explained the whole question sufficiently, or even in a way that you can understand my problem. But how should I deal with this? Should I restructure a lot of things, or is there a simple (not necessarily efficient/best) solution?
PS: I did not include any code, because my code is a mess/enormous, with lots of files and it is in Portuguese, but if needed I can edit the post or put the link to my repository.
14