BsASTFX.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsASTFX.h"
  4. #include "BsMMAlloc.h"
  5. #include <assert.h>
  6. OptionInfo OPTION_LOOKUP[] =
  7. {
  8. { OT_None, ODT_Int },
  9. { OT_Options, ODT_Complex },
  10. { OT_Separable, ODT_Bool },
  11. { OT_Priority, ODT_Int },
  12. { OT_Sort, ODT_Int },
  13. { OT_Transparent, ODT_Bool },
  14. { OT_Technique, ODT_Complex },
  15. { OT_Mixin, ODT_String },
  16. { OT_Raster, ODT_Complex },
  17. { OT_Depth, ODT_Complex },
  18. { OT_Stencil, ODT_Complex },
  19. { OT_Blend, ODT_Complex },
  20. { OT_FeatureSet, ODT_String },
  21. { OT_Pass, ODT_Complex },
  22. { OT_FillMode, ODT_Int },
  23. { OT_CullMode, ODT_Int },
  24. { OT_DepthBias, ODT_Float },
  25. { OT_SDepthBias, ODT_Float },
  26. { OT_DepthClip, ODT_Bool },
  27. { OT_Scissor, ODT_Bool },
  28. { OT_Multisample, ODT_Bool },
  29. { OT_AALine, ODT_Bool },
  30. { OT_DepthRead, ODT_Bool },
  31. { OT_DepthWrite, ODT_Bool },
  32. { OT_CompareFunc, ODT_Int },
  33. { OT_StencilReadMask, ODT_Int },
  34. { OT_StencilWriteMask, ODT_Int },
  35. { OT_StencilOpFront, ODT_Complex },
  36. { OT_StencilOpBack, ODT_Complex },
  37. { OT_PassOp, ODT_Int },
  38. { OT_Fail, ODT_Int },
  39. { OT_ZFail, ODT_Int },
  40. { OT_AlphaToCoverage, ODT_Bool },
  41. { OT_IndependantBlend, ODT_Bool },
  42. { OT_Target, ODT_Complex },
  43. { OT_Index, ODT_Int },
  44. { OT_Enabled, ODT_Bool },
  45. { OT_Color, ODT_Complex },
  46. { OT_Alpha, ODT_Complex },
  47. { OT_WriteMask, ODT_Int },
  48. { OT_Source, ODT_Int },
  49. { OT_Dest, ODT_Int },
  50. { OT_Op, ODT_Int },
  51. { OT_Identifier, ODT_String },
  52. { OT_Code, ODT_Complex },
  53. { OT_StencilRef, ODT_Int },
  54. { OT_Tags, ODT_Complex },
  55. { OT_TagValue, ODT_String },
  56. { OT_Variations, ODT_Complex },
  57. { OT_Variation, ODT_Complex },
  58. { OT_VariationValue, ODT_Int },
  59. };
  60. NodeOptions* nodeOptionsCreate(void* context)
  61. {
  62. static const int BUFFER_SIZE = 5;
  63. NodeOptions* options = (NodeOptions*)mmalloc(context, sizeof(NodeOptions));
  64. options->count = 0;
  65. options->bufferSize = BUFFER_SIZE;
  66. options->entries = (NodeOption*)mmalloc(context, sizeof(NodeOption) * options->bufferSize);
  67. memset(options->entries, 0, sizeof(NodeOption) * options->bufferSize);
  68. return options;
  69. }
  70. void nodeOptionDelete(NodeOption* option)
  71. {
  72. if (OPTION_LOOKUP[(int)option->type].dataType == ODT_Complex)
  73. {
  74. nodeDelete(option->value.nodePtr);
  75. option->value.nodePtr = 0;
  76. }
  77. else if (OPTION_LOOKUP[(int)option->type].dataType == ODT_String)
  78. {
  79. mmfree((void*)option->value.strValue);
  80. option->value.strValue = 0;
  81. }
  82. }
  83. void nodeOptionsDelete(NodeOptions* options)
  84. {
  85. int i = 0;
  86. for (i = 0; i < options->count; i++)
  87. nodeOptionDelete(&options->entries[i]);
  88. mmfree(options->entries);
  89. mmfree(options);
  90. }
  91. void nodeOptionsResize(void* context, NodeOptions* options, int size)
  92. {
  93. NodeOption* originalEntries = options->entries;
  94. int originalSize = options->bufferSize;
  95. int elementsToCopy = originalSize;
  96. int sizeToCopy = 0;
  97. options->bufferSize = size;
  98. if (options->count > options->bufferSize)
  99. options->count = options->bufferSize;
  100. if (elementsToCopy > size)
  101. elementsToCopy = size;
  102. sizeToCopy = elementsToCopy * sizeof(NodeOption);
  103. options->entries = (NodeOption*)mmalloc(context, sizeof(NodeOption) * options->bufferSize);
  104. memcpy(options->entries, originalEntries, sizeToCopy);
  105. memset(options->entries + elementsToCopy, 0, sizeof(NodeOption) * options->bufferSize - sizeToCopy);
  106. mmfree(originalEntries);
  107. }
  108. void nodeOptionsGrowIfNeeded(void* context, NodeOptions* options)
  109. {
  110. static const int BUFFER_GROW = 10;
  111. if (options->count == options->bufferSize)
  112. nodeOptionsResize(context, options, options->bufferSize + BUFFER_GROW);
  113. }
  114. void nodeOptionsAdd(void* context, NodeOptions* options, const NodeOption* option)
  115. {
  116. nodeOptionsGrowIfNeeded(context, options);
  117. options->entries[options->count] = *option;
  118. options->count++;
  119. }
  120. ASTFXNode* nodeCreate(void* context, NodeType type)
  121. {
  122. ASTFXNode* node = (ASTFXNode*)mmalloc(context, sizeof(ASTFXNode));
  123. node->options = nodeOptionsCreate(context);
  124. node->type = type;
  125. return node;
  126. }
  127. void nodeDelete(ASTFXNode* node)
  128. {
  129. nodeOptionsDelete(node->options);
  130. mmfree(node);
  131. }
  132. void nodePush(ParseState* parseState, ASTFXNode* node)
  133. {
  134. NodeLink* linkNode = (NodeLink*)mmalloc(parseState->memContext, sizeof(NodeLink));
  135. linkNode->next = parseState->nodeStack;
  136. linkNode->node = node;
  137. parseState->nodeStack = linkNode;
  138. parseState->topNode = node;
  139. }
  140. void nodePop(ParseState* parseState)
  141. {
  142. if (!parseState->nodeStack)
  143. return;
  144. NodeLink* toRemove = parseState->nodeStack;
  145. parseState->nodeStack = toRemove->next;
  146. if (parseState->nodeStack)
  147. parseState->topNode = parseState->nodeStack->node;
  148. else
  149. parseState->topNode = 0;
  150. mmfree(toRemove);
  151. }
  152. void beginCodeBlock(ParseState* parseState)
  153. {
  154. CodeString* codeString = (CodeString*)mmalloc(parseState->memContext, sizeof(CodeString));
  155. codeString->index = parseState->numCodeStrings;
  156. codeString->size = 0;
  157. codeString->capacity = 4096;
  158. codeString->code = mmalloc(parseState->memContext, codeString->capacity);
  159. codeString->next = parseState->codeStrings;
  160. parseState->numCodeStrings++;
  161. parseState->codeStrings = codeString;
  162. // Insert defines for code-blocks as we don't perform pre-processing within code blocks but we still want outer defines
  163. // to be recognized by them (Performing pre-processing for code blocks is problematic because it would require parsing
  164. // of all the language syntax in order to properly handle macro replacement).
  165. for (int i = 0; i < parseState->numDefines; i++)
  166. {
  167. const char* define = "#define ";
  168. appendCodeBlock(parseState, define, (int)strlen(define));
  169. appendCodeBlock(parseState, parseState->defines[i].name, (int)strlen(parseState->defines[i].name));
  170. if (parseState->defines[i].expr != 0)
  171. {
  172. appendCodeBlock(parseState, " ", 1);
  173. appendCodeBlock(parseState, parseState->defines[i].expr, (int)strlen(parseState->defines[i].expr));
  174. }
  175. appendCodeBlock(parseState, "\n", 1);
  176. }
  177. }
  178. void appendCodeBlock(ParseState* parseState, const char* value, int size)
  179. {
  180. CodeString* codeString = parseState->codeStrings;
  181. if ((codeString->size + size) > codeString->capacity)
  182. {
  183. int newCapacity = codeString->capacity;
  184. do
  185. {
  186. newCapacity *= 2;
  187. } while ((codeString->size + size) > newCapacity);
  188. char* newBuffer = mmalloc(parseState->memContext, newCapacity);
  189. memcpy(newBuffer, codeString->code, codeString->size);
  190. mmfree(codeString->code);
  191. codeString->code = newBuffer;
  192. codeString->capacity = newCapacity;
  193. }
  194. memcpy(&codeString->code[codeString->size], value, size);
  195. codeString->size += size;
  196. }
  197. int getCodeBlockIndex(ParseState* parseState)
  198. {
  199. return parseState->codeStrings->index;
  200. }
  201. char* getCurrentFilename(ParseState* parseState)
  202. {
  203. if (!parseState->includeStack)
  204. return NULL;
  205. return parseState->includeStack->data->filename;
  206. }
  207. void addDefine(ParseState* parseState, const char* value)
  208. {
  209. int defineIdx = parseState->numDefines;
  210. parseState->numDefines++;
  211. if(parseState->numDefines > parseState->defineCapacity)
  212. {
  213. int newCapacity = parseState->defineCapacity * 2;
  214. DefineEntry* newDefines = mmalloc(parseState->memContext, newCapacity * sizeof(DefineEntry));
  215. memcpy(newDefines, parseState->defines, parseState->defineCapacity * sizeof(DefineEntry));
  216. mmfree(parseState->defines);
  217. parseState->defines = newDefines;
  218. parseState->defineCapacity = newCapacity;
  219. }
  220. parseState->defines[defineIdx].name = mmalloc_strdup(parseState->memContext, value);
  221. parseState->defines[defineIdx].expr = 0;
  222. }
  223. void addDefineExpr(ParseState* parseState, const char* value)
  224. {
  225. int defineIdx = parseState->numDefines - 1;
  226. if(defineIdx < 0)
  227. {
  228. assert(0);
  229. return;
  230. }
  231. parseState->defines[defineIdx].expr = mmalloc_strdup(parseState->memContext, value);
  232. }
  233. int hasDefine(ParseState* parseState, const char* value)
  234. {
  235. for (int i = 0; i < parseState->numDefines; i++)
  236. {
  237. if (strcmp(parseState->defines[i].name, value) == 0)
  238. return 1;
  239. }
  240. return 0;
  241. }
  242. int isDefineEnabled(ParseState* parseState, const char* value)
  243. {
  244. for (int i = 0; i < parseState->numDefines; i++)
  245. {
  246. if (strcmp(parseState->defines[i].name, value) == 0)
  247. {
  248. if(parseState->defines[i].expr == 0)
  249. return 0;
  250. int val = atoi(parseState->defines[i].expr);
  251. return val != 0;
  252. }
  253. }
  254. return 0;
  255. }
  256. void removeDefine(ParseState* parseState, const char* value)
  257. {
  258. for (int i = 0; i < parseState->numDefines; i++)
  259. {
  260. if (strcmp(parseState->defines[i].name, value) == 0)
  261. {
  262. int remaining = parseState->numDefines - (i + 1);
  263. if(remaining > 0)
  264. memcpy(&parseState->defines[i], &parseState->defines[i + 1], remaining * sizeof(DefineEntry));
  265. parseState->numDefines--;
  266. }
  267. }
  268. }
  269. int pushConditional(ParseState* parseState, int state)
  270. {
  271. ConditionalData* conditional = mmalloc(parseState->memContext, sizeof(ConditionalData));
  272. conditional->enabled = state && (parseState->conditionalStack == 0 || parseState->conditionalStack->enabled);
  273. conditional->selfEnabled = state;
  274. conditional->next = parseState->conditionalStack;
  275. parseState->conditionalStack = conditional;
  276. return conditional->enabled;
  277. }
  278. int switchConditional(ParseState* parseState)
  279. {
  280. if (parseState->conditionalStack == 0)
  281. return 1;
  282. ConditionalData* conditional = parseState->conditionalStack;
  283. return setConditional(parseState, !conditional->selfEnabled);
  284. }
  285. int setConditional(ParseState* parseState, int state)
  286. {
  287. if (parseState->conditionalStack == 0)
  288. return 1;
  289. ConditionalData* conditional = parseState->conditionalStack;
  290. ConditionalData* parent = conditional->next;
  291. conditional->enabled = state && (parent == 0 || parent->enabled);
  292. conditional->selfEnabled = state;
  293. return conditional->enabled;
  294. }
  295. int popConditional(ParseState* parseState)
  296. {
  297. if (parseState->conditionalStack == 0)
  298. return 1;
  299. ConditionalData* conditional = parseState->conditionalStack;
  300. parseState->conditionalStack = conditional->next;
  301. mmfree(conditional);
  302. return parseState->conditionalStack == 0 || parseState->conditionalStack->enabled;
  303. }
  304. ParseState* parseStateCreate()
  305. {
  306. ParseState* parseState = (ParseState*)malloc(sizeof(ParseState));
  307. parseState->memContext = mmalloc_new_context();
  308. parseState->rootNode = nodeCreate(parseState->memContext, NT_Shader);
  309. parseState->topNode = 0;
  310. parseState->nodeStack = 0;
  311. parseState->includeStack = 0;
  312. parseState->includes = 0;
  313. parseState->codeStrings = 0;
  314. parseState->numCodeStrings = 0;
  315. parseState->numOpenBrackets = 0;
  316. parseState->hasError = 0;
  317. parseState->errorLine = 0;
  318. parseState->errorColumn = 0;
  319. parseState->errorMessage = 0;
  320. parseState->errorFile = 0;
  321. parseState->conditionalStack = 0;
  322. parseState->defineCapacity = 10;
  323. parseState->numDefines = 0;
  324. parseState->defines = mmalloc(parseState->memContext, parseState->defineCapacity * sizeof(DefineEntry));
  325. nodePush(parseState, parseState->rootNode);
  326. return parseState;
  327. }
  328. void parseStateDelete(ParseState* parseState)
  329. {
  330. while (parseState->nodeStack != 0)
  331. nodePop(parseState);
  332. nodeDelete(parseState->rootNode);
  333. mmalloc_free_context(parseState->memContext);
  334. free(parseState);
  335. }