-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(feat) code generator addition #7
Changes from 1 commit
d967f35
9f54bf8
3e7c8cc
f6ef8e2
9e4f3cd
3a9ebda
250d967
f613b93
b383f4f
2136c84
0488a10
8c4594e
8f3e3cf
7c999b4
6c07ed7
36d23ca
ee7382d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#include "code_generator.h" | ||
|
||
#include <stdio.h> | ||
#include <stdbool.h> | ||
|
||
// Assign a value to a variable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Take a look here:
So don't write any comments in .c files. It is better to move them to .h files and follow Doxygen format |
||
void generate_move(char *parameter_frame, char *parameter, char *variable_frame, char *variable) { | ||
fprintf(fd, "MOVE %s%s %s%s\n", parameter_frame, parameter, variable_frame, variable); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Following the task, there must be By the way, maybe it would be better to name function parameters according to the task - first and second are variable frame and variable, third and fourth - symbol frame and symbol. |
||
} | ||
|
||
// Create a new temporary frame | ||
void generate_create_frame() { | ||
fprintf(fd, "CREATEFRAME\n"); | ||
} | ||
|
||
// Push a frame to the stack | ||
void generate_push_frame() { | ||
fprintf(fd, "PUSHFRAME\n"); | ||
} | ||
|
||
// Pop a frame from the stack | ||
void generate_pop_frame() { | ||
fprintf(fd, "POPFRAME\n"); | ||
} | ||
|
||
// Define a new variable in the frame | ||
void generate_declaration(char *variable_frame, char *variable) { | ||
fprintf(fd, "DEFVAR %s%s\n", variable_frame, variable); | ||
} | ||
|
||
// Jump on a sign with return support | ||
void generate_call(char *label) { | ||
fprintf(fd, "CALL $%s\n", label); | ||
} | ||
|
||
// Put the value on the top of the stack | ||
void generate_push(char *variable_frame, char *variable) { | ||
fprintf(fd, "PUSHS %s%s\n", variable_frame, variable); | ||
} | ||
|
||
// Sum of two numerical values | ||
void generate_add(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "ADD LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and the following instructions always contains LF as a frame. Can this frame be changed or there is always used LF as a frame in these instructions? |
||
} | ||
|
||
// Subtraction of two numerical values | ||
void generate_sub(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "SUB LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Multiplication of two numerical values | ||
void generate_mul(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "MUL LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Division of two numerical values | ||
void generate_idiv(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "IDIV LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Compare two values for lower that | ||
void generate_lt(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "LT LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Compare two values for greater than | ||
void generate_gt(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "GT LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Compare two values for equality | ||
void generate_eq(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "EQ LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Compare two values with logical AND | ||
void generate_and(char *result, char *symbol1, char *symbol2) { | ||
fprintf(fd, "AND LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Compare two values with logical OR | ||
void generate_or(char *result, char *symbol1, char *symbol2) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Many functions are repeating in their arguments. Maybe it might be useful to union them into one universal function? For passing instruction keyword to this function can be used predefined enum with all instructions of similar type. |
||
fprintf(fd, "OR LF@%s LF@%s LF@%s\n", result, symbol1, symbol2); | ||
} | ||
|
||
// Compare two values with logical NOT | ||
void generate_not(char *result, char *symbol) { | ||
fprintf(fd, "NOT LF@%s LF@%s\n", result, symbol); | ||
} | ||
|
||
void generate_end() { | ||
printf("\nPOPFRAME"); | ||
printf("\nRETURN"); | ||
} | ||
|
||
int test_code_generator() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function should not exist, when tests with googletest will be added |
||
fd = fopen("test.txt", "w"); | ||
generate_move("GF", "a", "GF", "b"); | ||
generate_create_frame(); | ||
generate_push_frame(); | ||
generate_pop_frame(); | ||
generate_declaration("GF", "c"); | ||
generate_call("test"); | ||
generate_push("GF", "a"); | ||
generate_add("c", "a", "b"); | ||
generate_sub("c", "a", "b"); | ||
generate_mul("c", "a", "b"); | ||
generate_idiv("c", "a", "b"); | ||
generate_lt("c", "a", "b"); | ||
generate_gt("c", "a", "b"); | ||
generate_eq("c", "a", "b"); | ||
generate_and("c", "a", "b"); | ||
generate_or("c", "a", "b"); | ||
generate_not("c", "a"); | ||
fclose(fd); | ||
return 0; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
NickSettler marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#ifndef IFJ_PROJ_2022_CODE_GENERATOR_H | ||
NickSettler marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#define IFJ_PROJ_2022_CODE_GENERATOR_H | ||
|
||
FILE* fd; //file for testing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For testing you can use GoogleTest framework. Take a look at the tests directory. The |
||
|
||
void generate_move(char *parameter_frame, char *parameter, char *variable_frame, char *variable); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose we should add to every function a parameter. String to which function will append instruction string. So these functions can be easily used for tests. For this purpose is appropriate to use |
||
void generate_create_frame(); | ||
void generate_push_frame(); | ||
void generate_pop_frame(); | ||
void generate_declaration(char* variable_frame, char* variable); | ||
void generate_call(char *label); | ||
void generate_push(char* variable_frame, char* variable); | ||
void generate_add(char* result, char* symbol1, char* symbol2); | ||
void generate_sub (char* result, char* symbol1, char* symbol2); | ||
void generate_mul (char* result, char* symbol1, char* symbol2); | ||
void generate_idiv (char* result, char* symbol1, char* symbol2); | ||
void generate_lt (char* result, char* symbol1, char* symbol2); | ||
void generate_gt (char* result, char* symbol1, char* symbol2); | ||
void generate_eq (char* result, char* symbol1, char* symbol2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some functions are missing. Instruction set in the task file contains about 40 instructions. I've counted 14 here |
||
|
||
#endif //IFJ_PROJ_2022_CODE_GENERATOR_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Includes should be placed in .h file. The only .h file which should be included in .c file - is the header file. In your case - code_generator.h.