From aa318674e8e790eda7deefc021bb8e4c6877d59d Mon Sep 17 00:00:00 2001 From: lazaray <104470294+lazaray@users.noreply.github.com> Date: Fri, 6 May 2022 20:23:07 +0200 Subject: [PATCH] Add support for calculated defines to parser (#2463) * Add support for calculated defines to parser * Regenerate parser output --- parser/raylib_api.json | 4 +- parser/raylib_api.lua | 4 +- parser/raylib_api.txt | 4 +- parser/raylib_api.xml | 4 +- parser/raylib_parser.c | 159 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 156 insertions(+), 19 deletions(-) diff --git a/parser/raylib_api.json b/parser/raylib_api.json index 5006e206..5a6cffe5 100644 --- a/parser/raylib_api.json +++ b/parser/raylib_api.json @@ -26,13 +26,13 @@ }, { "name": "DEG2RAD", - "type": "UNKNOWN", + "type": "FLOAT_MATH", "value": "(PI/180.0f)", "description": "" }, { "name": "RAD2DEG", - "type": "UNKNOWN", + "type": "FLOAT_MATH", "value": "(180.0f/PI)", "description": "" }, diff --git a/parser/raylib_api.lua b/parser/raylib_api.lua index 2cbd388f..d4fb9a4d 100644 --- a/parser/raylib_api.lua +++ b/parser/raylib_api.lua @@ -26,13 +26,13 @@ return { }, { name = "DEG2RAD", - type = "UNKNOWN", + type = "FLOAT_MATH", value = "(PI/180.0f)", description = "" }, { name = "RAD2DEG", - type = "UNKNOWN", + type = "FLOAT_MATH", value = "(180.0f/PI)", description = "" }, diff --git a/parser/raylib_api.txt b/parser/raylib_api.txt index 10b9727c..18ef8aff 100644 --- a/parser/raylib_api.txt +++ b/parser/raylib_api.txt @@ -23,12 +23,12 @@ Define 004: PI Description: Define 005: DEG2RAD Name: DEG2RAD - Type: UNKNOWN + Type: FLOAT_MATH Value: (PI/180.0f) Description: Define 006: RAD2DEG Name: RAD2DEG - Type: UNKNOWN + Type: FLOAT_MATH Value: (180.0f/PI) Description: Define 007: RL_MALLOC(sz) diff --git a/parser/raylib_api.xml b/parser/raylib_api.xml index 917d26f5..c2bb720a 100644 --- a/parser/raylib_api.xml +++ b/parser/raylib_api.xml @@ -5,8 +5,8 @@ - - + + diff --git a/parser/raylib_parser.c b/parser/raylib_parser.c index 55d2d648..00751747 100644 --- a/parser/raylib_parser.c +++ b/parser/raylib_parser.c @@ -84,7 +84,22 @@ //---------------------------------------------------------------------------------- // Type of parsed define -typedef enum { UNKNOWN = 0, MACRO, GUARD, INT, LONG, FLOAT, DOUBLE, CHAR, STRING, COLOR } DefineType; +typedef enum { + UNKNOWN = 0, + MACRO, + GUARD, + INT, + INT_MATH, + LONG, + LONG_MATH, + FLOAT, + FLOAT_MATH, + DOUBLE, + DOUBLE_MATH, + CHAR, + STRING, + COLOR +} DefineType; // Define info data typedef struct DefineInfo { @@ -459,6 +474,124 @@ int main(int argc, char* argv[]) MemoryCopy(defines[defineIndex].desc, &linePtr[commentStart], commentLen); } + // Parse defines of type UNKNOWN to find calculated numbers + if (defines[defineIndex].type == UNKNOWN) + { + DefineType largestType = UNKNOWN; + bool isMath = true; + char *valuePtr = defines[defineIndex].value; + + for (int c = 0; c < TextLength(valuePtr); c++) + { + char ch = valuePtr[c]; + + // Skip operators and whitespace + if ((ch == '(') || + (ch == ')') || + (ch == '+') || + (ch == '-') || + (ch == '*') || + (ch == '/') || + (ch == ' ') || + (ch == '\t')) continue; + + // Read number operand + else if (isdigit(ch)) + { + bool isNumber = true, isFloat = false; + while (!((ch == '(') || + (ch == ')') || + (ch == '*') || + (ch == '/') || + (ch == ' ') || + (ch == '\t') || + (ch == '\0'))) + { + if (ch == '.') isFloat = true; + if (!(isdigit(ch) || + ((ch >= 'a') && (ch <= 'f')) || + ((ch >= 'A') && (ch <= 'F')) || + (ch == 'x') || + (ch == 'L') || + (ch == '.') || + (ch == '+') || + (ch == '-'))) + { + isNumber = false; + break; + } + c++; + ch = valuePtr[c]; + } + if (isNumber) + { + // Found a valid number -> update largestType + DefineType numberType; + if (isFloat) numberType = valuePtr[c - 1] == 'f' ? FLOAT_MATH : DOUBLE_MATH; + else numberType = valuePtr[c - 1] == 'L' ? LONG_MATH : INT_MATH; + + if (numberType > largestType) largestType = numberType; + } + else + { + isMath = false; + break; + } + } + + // Read string operand + else + { + int operandStart = c; + while (!((ch == '\0') || + (ch == ' ') || + (ch == '(') || + (ch == ')') || + (ch == '+') || + (ch == '-') || + (ch == '*') || + (ch == '/'))) + { + c++; + ch = valuePtr[c]; + } + int operandEnd = c; + int operandLength = operandEnd - operandStart; + + // Search previous defines for operand + bool foundOperand = false; + for (int previousDefineIndex = 0; previousDefineIndex < defineIndex; previousDefineIndex++) + { + if (IsTextEqual(defines[previousDefineIndex].name, &valuePtr[operandStart], operandLength)) + { + if ((defines[previousDefineIndex].type >= INT) && (defines[previousDefineIndex].type <= DOUBLE_MATH)) + { + // Found operand and it's a number -> update largestType + if (defines[previousDefineIndex].type > largestType) largestType = defines[previousDefineIndex].type; + foundOperand = true; + } + break; + } + } + if (!foundOperand) + { + isMath = false; + break; + } + } + } + + if (isMath) + { + // Define is a calculated number -> update type + if (largestType == INT) largestType = INT_MATH; + else if (largestType == LONG) largestType = LONG_MATH; + else if (largestType == FLOAT) largestType = FLOAT_MATH; + else if (largestType == DOUBLE) largestType = DOUBLE_MATH; + defines[defineIndex].type = largestType; + } + } + defineIndex++; } defineCount = defineIndex; @@ -1251,16 +1384,20 @@ static const char *StrDefineType(DefineType type) { switch (type) { - case UNKNOWN: return "UNKNOWN"; - case GUARD: return "GUARD"; - case MACRO: return "MACRO"; - case INT: return "INT"; - case LONG: return "LONG"; - case FLOAT: return "FLOAT"; - case DOUBLE: return "DOUBLE"; - case CHAR: return "CHAR"; - case STRING: return "STRING"; - case COLOR: return "COLOR"; + case UNKNOWN: return "UNKNOWN"; + case GUARD: return "GUARD"; + case MACRO: return "MACRO"; + case INT: return "INT"; + case INT_MATH: return "INT_MATH"; + case LONG: return "LONG"; + case LONG_MATH: return "LONG_MATH"; + case FLOAT: return "FLOAT"; + case FLOAT_MATH: return "FLOAT_MATH"; + case DOUBLE: return "DOUBLE"; + case DOUBLE_MATH: return "DOUBLE_MATH"; + case CHAR: return "CHAR"; + case STRING: return "STRING"; + case COLOR: return "COLOR"; } return ""; }