-
Notifications
You must be signed in to change notification settings - Fork 2
[feat] New Int types #46
Changes from all commits
4473c5c
c5f45b4
d4083f5
e4cc688
3155866
1f60f3a
87c4521
e0081a4
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 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,8 @@ | |||||||||||||
| #include "../../parser/structs/values.h" | ||||||||||||||
| #include "../../parser/structs/tree.h" | ||||||||||||||
|
|
||||||||||||||
| #include "../../lib/types.h" | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Parses the value into the buffer. | ||||||||||||||
| * @param buff the byte buffer. | ||||||||||||||
|
|
@@ -19,15 +21,42 @@ | |||||||||||||
| if(((AST_TREE_BRANCH*)value)->type == AST_TYPE_VALUE) { | ||||||||||||||
| AST_VALUE* val = (AST_VALUE*)value; | ||||||||||||||
|
|
||||||||||||||
| if(val->valueType[0] == 0x01) { //int32 | ||||||||||||||
| int num = atoi(val->value); | ||||||||||||||
| switch(*val->valueType) { | ||||||||||||||
| case INT32: | ||||||||||||||
| int num = atoi(val->value); | ||||||||||||||
| buff[index] = malloc(4); | ||||||||||||||
|
|
||||||||||||||
| ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[1] = (num >> 16) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[2] = (num >> 8) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[3] = num & 0xFF; | ||||||||||||||
|
|
||||||||||||||
| break; | ||||||||||||||
|
|
||||||||||||||
| case INT24: | ||||||||||||||
| num = atoi(val->value); | ||||||||||||||
|
Check notice on line 37 in src/ir/irs/values.c
|
||||||||||||||
| buff[index] = malloc(3); | ||||||||||||||
|
|
||||||||||||||
| ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[1] = (num >> 16) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[2] = (num >> 8) & 0xFF; | ||||||||||||||
| break; | ||||||||||||||
|
|
||||||||||||||
| buff[index] = malloc(4); | ||||||||||||||
| case INT16: | ||||||||||||||
| num = atoi(val->value); | ||||||||||||||
| buff[index] = malloc(2); | ||||||||||||||
|
|
||||||||||||||
| ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[1] = (num >> 16) & 0xFF; | ||||||||||||||
| break; | ||||||||||||||
|
Comment on lines
+49
to
+51
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. Correct bit shifting and array indexing in Similar to the Apply this diff: ((unsigned char*)buff[index])[0] = (num >> 8) & 0xFF;
((unsigned char*)buff[index])[1] = num & 0xFF;📝 Committable suggestion
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| case INT8: | ||||||||||||||
| num = atoi(val->value); | ||||||||||||||
| buff[index] = malloc(1); | ||||||||||||||
|
|
||||||||||||||
| ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF; | ||||||||||||||
| break; | ||||||||||||||
|
Comment on lines
+24
to
+58
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. 🛠️ Refactor suggestion Refactor repetitive code in the The Consider creating a helper function to handle the allocation and byte assignment: void allocateAndAssign(void** buffer, int index, int num, int byteSize) {
buffer[index] = malloc(byteSize);
for (int i = 0; i < byteSize; i++) {
((unsigned char*)buffer[index])[i] = (num >> (8 * (byteSize - i - 1))) & 0xFF;
}
}Then, refactor the switch(*val->valueType) {
case INT32:
- int num = atoi(val->value);
- buff[index] = malloc(4);
-
- ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF;
- ((unsigned char*)buff[index])[1] = (num >> 16) & 0xFF;
- ((unsigned char*)buff[index])[2] = (num >> 8) & 0xFF;
- ((unsigned char*)buff[index])[3] = num & 0xFF;
+ {
+ int num = atoi(val->value);
+ allocateAndAssign(buff, index, num, 4);
+ }
break;
case INT24:
- num = atoi(val->value);
- buff[index] = malloc(3);
-
- ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF;
- ((unsigned char*)buff[index])[1] = (num >> 16) & 0xFF;
- ((unsigned char*)buff[index])[2] = (num >> 8) & 0xFF;
+ {
+ int num = atoi(val->value);
+ allocateAndAssign(buff, index, num, 3);
+ }
break;
case INT16:
case INT8:
// Similar refactoring for INT16 and INT8
}
Comment on lines
+57
to
+58
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. Adjust bit shifting in Shifting by 24 bits in the Apply this diff: - ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF;
+ ((unsigned char*)buff[index])[0] = num & 0xFF;📝 Committable suggestion
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| ((unsigned char*)buff[index])[0] = (num >> 24) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[1] = (num >> 16) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[2] = (num >> 8) & 0xFF; | ||||||||||||||
| ((unsigned char*)buff[index])[3] = num & 0xFF; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
@@ -37,6 +66,16 @@ | |||||||||||||
| * @param type the type's byte indentifier. | ||||||||||||||
| */ | ||||||||||||||
| int getValueSize(unsigned char type) { | ||||||||||||||
| if(type == 0x01) return 4; // int32 type -> 4 bytes | ||||||||||||||
| switch(type) { | ||||||||||||||
| case INT32: | ||||||||||||||
| return 32; | ||||||||||||||
| case INT24: | ||||||||||||||
| return 24; | ||||||||||||||
| case INT16: | ||||||||||||||
| return 16; | ||||||||||||||
| case INT8: | ||||||||||||||
| return 8; | ||||||||||||||
|
|
||||||||||||||
| } | ||||||||||||||
| return 0; | ||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,10 @@ typedef enum { | |
| NONE, | ||
| MATH_OP, | ||
|
|
||
| TYPE_INT32 | ||
| TYPE_INT32, | ||
| TYPE_INT24, | ||
| TYPE_INT16, | ||
| TYPE_INT8 | ||
|
Comment on lines
+27
to
+30
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. 💡 Codebase verification Enum values should be explicitly aligned between TOKEN_TYPE and LIB_TYPES The integer type tokens in TYPE_INT32 = 0x01,
TYPE_INT24 = 0x02,
TYPE_INT16 = 0x03,
TYPE_INT8 = 0x04🔗 Analysis chainEnsure token types match the corresponding data types and maintain enum consistency. The token types added for the integer types should align with the values defined in Please confirm that the token types' values correspond correctly with the types' values defined in 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Verify that TOKEN_TYPE enum values align with LIB_TYPES enum values.
# Extract enum values from tokens.h
grep -E 'TYPE_INT(8|16|24|32)' src/lexer/tokens.h | cat -n
# Extract enum values from types.h
grep -E 'INT(8|16|24|32)' src/lib/types.h | cat -n
Length of output: 301 Script: #!/bin/bash
# Search for patterns where both TYPE_INT* and INT* are used together
rg -U "TYPE_INT.*INT[0-9]|INT[0-9].*TYPE_INT" -A 2 -B 2
# Search for any conversion or mapping between these types
ast-grep --pattern 'case TYPE_INT$_: return INT$_;'
Length of output: 111 Script: #!/bin/bash
# Search for switch statements or conditions handling token types
ast-grep --pattern 'switch ($expr) { case TYPE_INT$_: $$$}'
# Search for files that might handle type conversions
fd -t f "type" -t f "convert" -t f "parser"
# Look for any token type handling code
rg -l "TYPE_INT" --type cpp
Length of output: 296 |
||
| } TOKEN_TYPE; | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /** | ||
| * Standart Quickfall types. | ||
| */ | ||
|
|
||
| #ifndef LIB_TYPES_H | ||
| #define LIB_TYPES_H | ||
|
|
||
| typedef enum LIB_TYPES { | ||
|
|
||
| VOID = 0x00, | ||
|
|
||
| // Numeric types | ||
| INT32 = 0x01, | ||
| INT24 = 0x02, | ||
| INT16 = 0x03, | ||
| INT8 = 0x04 | ||
|
|
||
| } LIB_TYPES; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,23 +11,31 @@ | |
|
|
||
| #include "../../lexer/lexer.h" | ||
|
|
||
| #include "../../lib/types.h" | ||
|
|
||
| /** | ||
| * Parses an AST value on the lexer result. | ||
| * @param result the Lexer result. | ||
| * @param index the index of the start of the parsing. | ||
| * @param exceptedType The excepted type of token. | ||
| */ | ||
| AST_VALUE* parseASTValue(LEXER_RESULT result, int index) { | ||
| AST_VALUE* parseASTValue(LEXER_RESULT result, int index, LIB_TYPES exceptedType) { | ||
| AST_VALUE* value = malloc(sizeof(AST_VALUE)); | ||
| value->astType = AST_TYPE_VALUE; | ||
|
Comment on lines
23
to
24
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. Add memory leak protection The code should handle malloc failure and free allocated memory on error paths. AST_VALUE* value = malloc(sizeof(AST_VALUE));
+ if (!value) {
+ printf("Memory allocation failed for AST_VALUE\n");
+ return NULL;
+ }
value->astType = AST_TYPE_VALUE;
switch(exceptedType) {
// ... cases ...
}
value->valueType = malloc(1);
+ if (!value->valueType) {
+ printf("Memory allocation failed for valueType\n");
+ free(value);
+ return NULL;
+ }Also applies to: 36-37 |
||
|
|
||
| switch(result.tokens[index].type) { | ||
| case NUMBER: | ||
| switch(exceptedType) { | ||
| case INT32: | ||
| case INT24: | ||
| case INT16: | ||
| case INT8: | ||
| if(result.tokens[index].type != NUMBER) { | ||
| printf("Excepted number as value!\n"); | ||
| return NULL; | ||
| } | ||
|
|
||
| value->valueType = malloc(1); | ||
| value->valueType[0] = 0x01; //i32 | ||
| value->valueType[0] = exceptedType; | ||
|
Comment on lines
24
to
+37
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. 💡 Codebase verification Bounds checking is indeed necessary for safe integer parsing The codebase confirms that:
Implementation suggestions:
The original review comment's suggestion to add bounds checking is critical for preventing integer overflow and ensuring type safety. 🔗 Analysis chainAdd bounds checking for number values The code should validate that the number value fits within the bounds of the specified integer type. switch(exceptedType) {
case INT32:
+ if (!isValidInt32(result.tokens[index].value)) {
+ printf("Number %s exceeds INT32 bounds at index %d\n", result.tokens[index].value, index);
+ return NULL;
+ }
break;
case INT24:
+ if (!isValidInt24(result.tokens[index].value)) {
+ printf("Number %s exceeds INT24 bounds at index %d\n", result.tokens[index].value, index);
+ return NULL;
+ }
break;
// Similar checks for INT16 and INT8
}Let me help you implement the validation functions. Would you like me to generate them? 🏁 Scripts executedThe following scripts were executed for the analysis: Error: No shell scripts found Script: #!/bin/bash
# Search for existing validation functions
ast-grep --pattern 'isValidInt$_'
# Look for token structure definition
rg -A 5 "struct\s+[Tt]oken"
# Search for bounds checking patterns
rg -B 2 -A 2 "(INT32|INT24|INT16|INT8).*(bounds|range|limit|max|min)"
Length of output: 137 Script: #!/bin/bash
# Find integer type definitions and related code
rg -l "typedef.*int|enum.*INT"
# Look for number parsing/validation code
rg -B 2 -A 5 "NUMBER.*token|token.*NUMBER"
# Find token value handling
fd "token" --type f --exec rg -l "value.*=|=.*value"
Length of output: 564 Script: #!/bin/bash
# Find token structure in header files
fd -e h -e hpp --exec rg -l "struct.*[Tt]oken"
# Look for number parsing implementation
rg -B 3 -A 3 "atoi|strtol|sscanf.*number"
# Find integer type definitions
fd -e h --exec rg -l "INT(32|24|16|8)"
Length of output: 2257 Script: #!/bin/bash
# Check integer type definitions
cat src/lib/types.h
# Look at token structure
cat src/lexer/tokens.h
Length of output: 823 |
||
| break; | ||
| default: | ||
| printf("Error: Couldn't parse token %d as a value!\n", result.tokens[index].type); | ||
| return value; | ||
| } | ||
|
|
||
| value->endingIndex = index + 1; | ||
|
|
@@ -40,15 +48,16 @@ AST_VALUE* parseASTValue(LEXER_RESULT result, int index) { | |
| * Parses an actual expression as value instead of just one token. | ||
| * @param result the Lexer result. | ||
| * @param index the index of the start of the parsing. | ||
| * @param exceptedType The excepted type of token. | ||
| */ | ||
| void* parseValueGroup(LEXER_RESULT result, int index) { | ||
| void* parseValueGroup(LEXER_RESULT result, int index, LIB_TYPES exceptedType) { | ||
| switch(result.tokens[index].type) { | ||
| case NUMBER: | ||
| if(result.tokens[index + 1].type == MATH_OP) { | ||
| //todo: parse math op. | ||
| } | ||
|
|
||
| return parseASTValue(result, index); | ||
| return parseASTValue(result, index, exceptedType); | ||
| break; | ||
| default: | ||
| printf("Error: couldn't parse value token group!\n"); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,11 +26,16 @@ AST_VARIABLE_DEC* parseASTVariableDeclaration(LEXER_RESULT result, int index) { | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| switch(result.tokens[index].type) { | ||||||||||||||||||||||||||||||||||||||||||
| case TYPE_INT32: | ||||||||||||||||||||||||||||||||||||||||||
| var->type[0] = 0x01; | ||||||||||||||||||||||||||||||||||||||||||
| case TYPE_INT24: | ||||||||||||||||||||||||||||||||||||||||||
| case TYPE_INT16: | ||||||||||||||||||||||||||||||||||||||||||
| case TYPE_INT8: | ||||||||||||||||||||||||||||||||||||||||||
| var->type[0] = (result.tokens[index].type - TYPE_INT32) + 0x01; | ||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| case VAR: | ||||||||||||||||||||||||||||||||||||||||||
| var->type[0] = 0x00; | ||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||||||||
| printf("Error: Disallowed token as variable type!\n"); | ||||||||||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -44,14 +49,14 @@ AST_VARIABLE_DEC* parseASTVariableDeclaration(LEXER_RESULT result, int index) { | |||||||||||||||||||||||||||||||||||||||||
| var->name = result.tokens[index + 1].value; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if(result.tokens[index + 2].type == DECLARE) { | ||||||||||||||||||||||||||||||||||||||||||
| void* value = parseValueGroup(result, index + 3); | ||||||||||||||||||||||||||||||||||||||||||
| void* value = parseValueGroup(result, index + 3, var->type[0]); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if(value == NULL) { | ||||||||||||||||||||||||||||||||||||||||||
| printf("Error: Couldn't parse variable value group!\n"); | ||||||||||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| var->endingIndex = ((AST_TREE_BRANCH*)value)->endingIndex; | ||||||||||||||||||||||||||||||||||||||||||
| var->endingIndex = ((AST_TREE_BRANCH*)value)->endingIndex - 1; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| var->value = value; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -71,15 +76,15 @@ AST_VARIABLE_MOD* parseVariableModification(LEXER_RESULT result, int index) { | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| mod->name = result.tokens[index].value; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| void* value = parseValueGroup(result, index + 2); | ||||||||||||||||||||||||||||||||||||||||||
| void* value = parseValueGroup(result, index + 2, 0x01); // todo: change later | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if(value == NULL) { | ||||||||||||||||||||||||||||||||||||||||||
| printf("Error: Couldn't parse variable value group in redefinition!\n"); | ||||||||||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| mod->value = value; | ||||||||||||||||||||||||||||||||||||||||||
| mod->endingIndex = ((AST_TREE_BRANCH*)value)->endingIndex; | ||||||||||||||||||||||||||||||||||||||||||
| mod->endingIndex = ((AST_TREE_BRANCH*)value)->endingIndex - 1; | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+79
to
+87
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. Fix memory leak in error path The static analyzer detected a memory leak when parseValueGroup returns NULL. void* value = parseValueGroup(result, index + 2, 0x01);
if(value == NULL) {
printf("Error: Couldn't parse variable value group in redefinition!\n");
+ free(mod);
return NULL;
}📝 Committable suggestion
Suggested change
🧰 Tools🪛 cppcheck (2.10-2)[error] 83-83: Memory leak (memleak) |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return mod; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
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.
Correct bit shifting in
INT24case.In the
INT24case, the bit shifting incorrectly starts from 24 bits, which exceeds the size of a 24-bit integer. Adjust the shifts to correctly extract the bytes.Apply this diff to fix the bit shifting:
📝 Committable suggestion