Skip to content
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

Merged
merged 17 commits into from
Oct 29, 2022
Merged

(feat) code generator addition #7

merged 17 commits into from
Oct 29, 2022

Conversation

Defancet
Copy link
Collaborator

@Defancet Defancet commented Oct 13, 2022

Started working on code generator, added working with the frame and calling functions instructions, as well as arithmetic, relational, boolean and conversion instructions

…alling functions instructions, as well as arithmetic, relational, boolean and conversion instructions
@Defancet Defancet added the feature New feature or request label Oct 13, 2022
@Defancet Defancet changed the title (feat)code generator addition (feat) code generator addition Oct 13, 2022
Copy link
Owner

@NickSettler NickSettler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following changes can be made:

  • addition of the tests using googletest
  • proper file and function comments according to the task and code style in the project
  • addition of the missing functions
  • fixing some existing functions (if needed)
  • using string_t in all functions
  • refactoring some functions not to repeat them

#include <stdio.h>
#include <stdbool.h>

// Assign a value to a variable
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look here:

Functions should be commented in Doxygen style.

For example this function declaration should be commented like

/**
 * Creates tree node with value
 * @param value value in the node
 * @return pointer to the tree node
 */
tree_node *create_node(int value);

It is enough to comment just function declarations, without commenting implementation in C files. Your IDE will probably automatically highlight such a comment as a function comment. First and next lines contain function description. There may be some keywords starting with @ sign after them. IDE may also suggest some keywords. Probably will be needed only @param which is used to describe function parameter and @return which is used to describe what is returned from function.

So don't write any comments in .c files. It is better to move them to .h files and follow Doxygen format

#include "code_generator.h"

#include <stdio.h>
#include <stdbool.h>
Copy link
Owner

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.


// Assign a value to a variable
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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the task, there must be @ signs between frame and variable name in the MOVE instruction

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.


FILE* fd; //file for testing

void generate_move(char *parameter_frame, char *parameter, char *variable_frame, char *variable);
Copy link
Owner

Choose a reason for hiding this comment

The 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 string_t type. Its function string_append_string can be used to append a custom char*.

src/code_generator.h Show resolved Hide resolved
#ifndef IFJ_PROJ_2022_CODE_GENERATOR_H
#define IFJ_PROJ_2022_CODE_GENERATOR_H

FILE* fd; //file for testing
Copy link
Owner

Choose a reason for hiding this comment

The 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 LexicalAnalyzerTest for now is the largest test. You can use it as an example for writing own tests. IMHO, it maybe enough to add a test for each function and tests, which will have more than a one function - just to check line breaks and stuff like that.

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);
Copy link
Owner

Choose a reason for hiding this comment

The 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

printf("\nRETURN");
}

int test_code_generator() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should not exist, when tests with googletest will be added


// 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);
Copy link
Owner

Choose a reason for hiding this comment

The 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?

}

// Compare two values with logical OR
void generate_or(char *result, char *symbol1, char *symbol2) {
Copy link
Owner

Choose a reason for hiding this comment

The 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.

@NickSettler NickSettler added this to the Sprint 2 milestone Oct 13, 2022
@NickSettler NickSettler linked an issue Oct 13, 2022 that may be closed by this pull request
@Defancet
Copy link
Collaborator Author

Needs to be done:

understand how to use string_t type
learn how to write google tests

@NickSettler NickSettler modified the milestones: Sprint 2, Sprint 3 Oct 17, 2022
Copy link
Owner

@NickSettler NickSettler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request of the following changes:

  • Code style changes
  • Comments fixing
  • Refactor and performance changes

* @author xkalut00, Maksim Kalutski
* @file code_generator.c
* @brief Code generator source file
* @date ??.10.2022
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Date should be set

void generate_operation(instructions_t instruction, char *result, char *symbol1, char *symbol2) {
switch (instruction) {
case ADD:
fprintf(fd, "ADD LF@%s LF@%s LF@%s\n", result, symbol1, symbol2);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we have discussed, this can be changed to other way without switch case. You can create an enum with string key values. Or you can create a numbered enum an string array with values ordered in the same order as enum. So than you'll be able to use its values instead of switch..case like this

fprintf(fd, operations[instruction], ...);

Take a look at #13 for an example. In summary, we should avoid such large repeating constructions in our code

}

void generate_stack_operation(stack_instructions_t instruction, char *result, char *symbol1, char *symbol2) {
switch (instruction) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This switch case can be also changed in the way described previously. Also switch..case constructions down can be changed this way


#include "code_generator.h"

void generate_move(char *variable_frame, char *variable, char *symbol_frame, char *symbol) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frames are actually predefined: GF, LF and TF. Maybe we can list them as an enumeration and pass them to code generator functions instead of passing them as a string

/**
* @brief function for choosing an arithmetic operation using a switch case
* ADDS/SUBS/MULS/DIVS/IDIVS are stack versions of ADD/SUB/MUL/DIV/IDIV
* @param *operation stack operation
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameter name in documentation doesn't match with the name of function parameter. They should be the same. I'm not sured, maybe other comments also have wrong parameter name

src/errors.c Outdated
@@ -1 +1,2 @@
#include "errors.h"
typedef int make_iso_compilers_happy;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removed

Copy link
Owner

@NickSettler NickSettler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some refactoring changes


void generate_clear_stack() {
fprintf(fd, "LABEL clear_stack\n");
fprintf(fd, "MOVE GT@clear_var bool@true\n");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are using frpintf here, so in these big functions you can also replace frame with its variable using enum

CONCAT,
STRLEN,
GETCHAR,
SETCHAR,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be good to add some prefixes to all these enum members and to make something like CODE_GEN_ADD_INSTRUCTION. Other modules may have also something names ADD, so we need to be able to differ one thing from another

NickSettler
NickSettler previously approved these changes Oct 28, 2022
NickSettler
NickSettler previously approved these changes Oct 29, 2022
@Defancet Defancet merged commit 6316154 into master Oct 29, 2022
@NickSettler NickSettler deleted the code_generator_addition branch November 8, 2022 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Code generator functions addition
4 participants