1 /*************************************************************************/
2 /* shader_language.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30 #include "shader_language.h"
31 #include "os/os.h"
32 #include "print_string.h"
_is_text_char(CharType c)33 static bool _is_text_char(CharType c) {
34
35 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
36 }
37
_is_number(CharType c)38 static bool _is_number(CharType c) {
39
40 return (c >= '0' && c <= '9');
41 }
42
_is_hex(CharType c)43 static bool _is_hex(CharType c) {
44
45 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
46 }
47
48 const char *ShaderLanguage::token_names[TK_MAX] = {
49 "EMPTY",
50 "INDENTIFIER",
51 "TRUE",
52 "FALSE",
53 "REAL_CONSTANT",
54 "TYPE_VOID",
55 "TYPE_BOOL",
56 "TYPE_FLOAT",
57 "TYPE_VEC2",
58 "TYPE_VEC3",
59 "TYPE_VEC4",
60 "TYPE_MAT2",
61 "TYPE_MAT3",
62 "TYPE_MAT4",
63 "TYPE_TEXTURE",
64 "TYPE_CUBEMAP",
65 "TYPE_COLOR",
66 "OP_EQUAL",
67 "OP_NOT_EQUAL",
68 "OP_LESS",
69 "OP_LESS_EQUAL",
70 "OP_GREATER",
71 "OP_GREATER_EQUAL",
72 "OP_AND",
73 "OP_OR",
74 "OP_NOT",
75 "OP_ADD",
76 "OP_SUB",
77 "OP_MUL",
78 "OP_DIV",
79 "OP_NEG",
80 "OP_ASSIGN",
81 "OP_ASSIGN_ADD",
82 "OP_ASSIGN_SUB",
83 "OP_ASSIGN_MUL",
84 "OP_ASSIGN_DIV",
85 "CF_IF",
86 "CF_ELSE",
87 "CF_RETURN",
88 "BRACKET_OPEN",
89 "BRACKET_CLOSE",
90 "CURLY_BRACKET_OPEN",
91 "CURLY_BRACKET_CLOSE",
92 "PARENTHESIS_OPEN",
93 "PARENTHESIS_CLOSE",
94 "COMMA",
95 "SEMICOLON",
96 "PERIOD",
97 "UNIFORM",
98 "ERROR",
99 };
100
read_token(const CharType * p_text,int p_len,int & r_line,int & r_chars)101 ShaderLanguage::Token ShaderLanguage::read_token(const CharType *p_text, int p_len, int &r_line, int &r_chars) {
102
103 #define GETCHAR(m_idx) ((m_idx < p_len) ? p_text[m_idx] : CharType(0))
104
105 r_chars = 1; //by default everything eats one char
106 switch (GETCHAR(0)) {
107
108 case '\t':
109 case '\r':
110 case ' ':
111 return Token();
112 case '\n':
113 r_line++;
114 return Token();
115 case '/': {
116
117 switch (GETCHAR(1)) {
118 case '*': { // block comment
119
120 while (true) {
121 if (GETCHAR(r_chars + 1) == 0) {
122 r_chars += 1;
123 break;
124 }
125 if (GETCHAR(r_chars + 1) == '*' && GETCHAR(r_chars + 2) == '/') {
126 r_chars += 3;
127 break;
128 }
129 if (GETCHAR(r_chars + 1) == '\n') {
130 r_line++;
131 }
132
133 r_chars++;
134 }
135
136 return Token();
137
138 } break;
139 case '/': { // line comment skip
140
141 while (GETCHAR(r_chars + 1) != '\n' && GETCHAR(r_chars + 1) != 0) {
142 r_chars++;
143 }
144 r_chars++;
145 //r_line++;
146
147 return Token();
148
149 } break;
150 case '=': { // diveq
151
152 r_chars = 2;
153 return Token(TK_OP_ASSIGN_DIV);
154
155 } break;
156 default:
157 return Token(TK_OP_DIV);
158 }
159 } break;
160 case '=': {
161 if (GETCHAR(1) == '=') {
162 r_chars++;
163 return Token(TK_OP_EQUAL);
164 }
165
166 return Token(TK_OP_ASSIGN);
167
168 } break;
169 case '<': {
170 if (GETCHAR(1) == '=') {
171 r_chars++;
172 return Token(TK_OP_LESS_EQUAL);
173 } /*else if (GETCHAR(1)=='<') {
174 r_chars++;
175 if (GETCHAR(2)=='=') {
176 r_chars++;
177 return Token(TK_OP_ASSIGN_SHIFT_LEFT);
178 }
179
180 return Token(TK_OP_SHIFT_LEFT);
181 }*/
182
183 return Token(TK_OP_LESS);
184
185 } break;
186 case '>': {
187 if (GETCHAR(1) == '=') {
188 r_chars++;
189 return Token(TK_OP_GREATER_EQUAL);
190 } /* else if (GETCHAR(1)=='<') {
191 r_chars++;
192 if (GETCHAR(2)=='=') {
193 r_chars++;
194 return Token(TK_OP_ASSIGN_SHIFT_RIGHT);
195 }
196
197 return Token(TK_OP_SHIFT_RIGHT);
198 }*/
199
200 return Token(TK_OP_GREATER);
201
202 } break;
203 case '!': {
204 if (GETCHAR(1) == '=') {
205 r_chars++;
206 return Token(TK_OP_NOT_EQUAL);
207 }
208
209 return Token(TK_OP_NOT);
210
211 } break;
212 //case '"' //string - no strings in shader
213 //case '\'' //string - no strings in shader
214 case '{':
215 return Token(TK_CURLY_BRACKET_OPEN);
216 case '}':
217 return Token(TK_CURLY_BRACKET_CLOSE);
218 //case '[':
219 // return Token(TK_BRACKET_OPEN);
220 //case ']':
221 // return Token(TK_BRACKET_CLOSE);
222 case '(':
223 return Token(TK_PARENTHESIS_OPEN);
224 case ')':
225 return Token(TK_PARENTHESIS_CLOSE);
226 case ',':
227 return Token(TK_COMMA);
228 case ';':
229 return Token(TK_SEMICOLON);
230 //case '?':
231 // return Token(TK_QUESTION_MARK);
232 //case ':':
233 // return Token(TK_COLON); //for methods maybe but now useless.
234 //case '^':
235 // return Token(TK_OP_BIT_XOR);
236 //case '~':
237 // return Token(TK_OP_BIT_INVERT);
238 case '&': {
239
240 if (GETCHAR(1) == '&') {
241
242 r_chars++;
243 return Token(TK_OP_AND);
244 }
245
246 return Token(TK_ERROR, "Unknown character");
247
248 /*
249 if (GETCHAR(1)=='=') {
250 r_chars++;
251 return Token(TK_OP_ASSIGN_BIT_AND);
252 } else if (GETCHAR(1)=='&') {
253 r_chars++;
254 return Token(TK_OP_AND);
255 }
256 return TK_OP_BIT_AND;*/
257 } break;
258 case '|': {
259
260 if (GETCHAR(1) == '|') {
261
262 r_chars++;
263 return Token(TK_OP_OR);
264 }
265
266 return Token(TK_ERROR, "Unknown character");
267
268 /*
269 if (GETCHAR(1)=='=') {
270 r_chars++;
271 return Token(TK_OP_ASSIGN_BIT_OR);
272 } else if (GETCHAR(1)=='|') {
273 r_chars++;
274 return Token(TK_OP_OR);
275 }
276 return TK_OP_BIT_OR;
277 */
278 } break;
279 case '*': {
280
281 if (GETCHAR(1) == '=') {
282 r_chars++;
283 return Token(TK_OP_ASSIGN_MUL);
284 }
285 return TK_OP_MUL;
286 } break;
287 case '+': {
288
289 if (GETCHAR(1) == '=') {
290 r_chars++;
291 return Token(TK_OP_ASSIGN_ADD);
292 } /*else if (GETCHAR(1)=='+') {
293
294 r_chars++;
295 return Token(TK_OP_PLUS_PLUS);
296 }*/
297
298 return TK_OP_ADD;
299 } break;
300 case '-': {
301
302 if (GETCHAR(1) == '=') {
303 r_chars++;
304 return Token(TK_OP_ASSIGN_SUB);
305 } /* else if (GETCHAR(1)=='-') {
306
307 r_chars++;
308 return Token(TK_OP_MINUS_MINUS);
309 }*/
310
311 return TK_OP_SUB;
312 } break;
313 /*case '%': {
314
315 if (GETCHAR(1)=='=') {
316 r_chars++;
317 return Token(TK_OP_ASSIGN_MOD);
318 }
319
320 return TK_OP_MOD;
321 } break;*/
322 default: {
323
324 if (_is_number(GETCHAR(0)) || (GETCHAR(0) == '.' && _is_number(GETCHAR(1)))) {
325 // parse number
326 bool period_found = false;
327 bool exponent_found = false;
328 bool hexa_found = false;
329 bool sign_found = false;
330
331 String str;
332 int i = 0;
333
334 while (true) {
335 if (GETCHAR(i) == '.') {
336 if (period_found || exponent_found)
337 return Token(TK_ERROR, "Invalid numeric constant");
338 period_found = true;
339 } else if (GETCHAR(i) == 'x') {
340 if (hexa_found || str.length() != 1 || str[0] != '0')
341 return Token(TK_ERROR, "Invalid numeric constant");
342 hexa_found = true;
343 } else if (GETCHAR(i) == 'e') {
344 if (hexa_found || exponent_found)
345 return Token(TK_ERROR, "Invalid numeric constant");
346 exponent_found = true;
347 } else if (_is_number(GETCHAR(i))) {
348 //all ok
349 } else if (hexa_found && _is_hex(GETCHAR(i))) {
350
351 } else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
352 if (sign_found)
353 return Token(TK_ERROR, "Invalid numeric constant");
354 sign_found = true;
355 } else
356 break;
357
358 str += CharType(GETCHAR(i));
359 i++;
360 }
361
362 if (!_is_number(str[str.length() - 1]))
363 return Token(TK_ERROR, "Invalid numeric constant");
364
365 r_chars += str.length() - 1;
366 return Token(TK_REAL_CONSTANT, str);
367 /*
368 if (period_found)
369 return Token(TK_NUMBER_REAL,str);
370 else
371 return Token(TK_NUMBER_INTEGER,str);*/
372 }
373
374 if (GETCHAR(0) == '.') {
375 //parse period
376 return Token(TK_PERIOD);
377 }
378
379 if (_is_text_char(GETCHAR(0))) {
380 // parse identifier
381 String str;
382 str += CharType(GETCHAR(0));
383
384 while (_is_text_char(GETCHAR(r_chars))) {
385
386 str += CharType(GETCHAR(r_chars));
387 r_chars++;
388 }
389
390 //see if keyword
391 struct _kws {
392 TokenType token;
393 const char *text;
394 };
395 static const _kws keyword_list[] = {
396 { TK_TRUE, "true" },
397 { TK_FALSE, "false" },
398 { TK_TYPE_VOID, "void" },
399 { TK_TYPE_BOOL, "bool" },
400 /*{TK_TYPE_INT,"int"},
401 {TK_TYPE_INT2,"int2"},
402 {TK_TYPE_INT3,"int3"},
403 {TK_TYPE_INT4,"int4"},*/
404 { TK_TYPE_FLOAT, "float" },
405 /*{TK_TYPE_FLOAT2,"float2"},
406 {TK_TYPE_FLOAT3,"float3"},
407 {TK_TYPE_FLOAT4,"float4"},*/
408 { TK_TYPE_VEC2, "vec2" },
409 { TK_TYPE_VEC3, "vec3" },
410 { TK_TYPE_VEC4, "vec4" },
411 { TK_TYPE_TEXTURE, "texture" },
412 { TK_TYPE_CUBEMAP, "cubemap" },
413 { TK_TYPE_COLOR, "color" },
414
415 { TK_TYPE_MAT2, "mat2" },
416 /*{TK_TYPE_MAT3,"mat3"},
417 {TK_TYPE_MAT4,"mat3"},*/
418 { TK_TYPE_MAT3, "mat3" },
419 { TK_TYPE_MAT4, "mat4" },
420 { TK_CF_IF, "if" },
421 { TK_CF_ELSE, "else" },
422 /*
423 {TK_CF_FOR,"for"},
424 {TK_CF_WHILE,"while"},
425 {TK_CF_DO,"do"},
426 {TK_CF_SWITCH,"switch"},
427 {TK_CF_BREAK,"break"},
428 {TK_CF_CONTINUE,"continue"},*/
429 { TK_CF_RETURN, "return" },
430 { TK_UNIFORM, "uniform" },
431 { TK_ERROR, NULL }
432 };
433
434 int idx = 0;
435
436 while (keyword_list[idx].text) {
437
438 if (str == keyword_list[idx].text)
439 return Token(keyword_list[idx].token);
440 idx++;
441 }
442
443 return Token(TK_INDENTIFIER, str);
444 }
445
446 if (GETCHAR(0) > 32)
447 return Token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)) + ": '" + String::chr(GETCHAR(0)) + "'");
448 else
449 return Token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)));
450
451 } break;
452 }
453
454 ERR_PRINT("BUG");
455 return Token();
456 }
457
tokenize(const String & p_text,Vector<Token> * p_tokens,String * r_error,int * r_err_line,int * r_err_column)458 Error ShaderLanguage::tokenize(const String &p_text, Vector<Token> *p_tokens, String *r_error, int *r_err_line, int *r_err_column) {
459
460 int len = p_text.length();
461 int pos = 0;
462
463 int line = 0;
464 int col = 0;
465
466 while (pos < len) {
467
468 int advance = 0;
469 int prev_line = line;
470 Token t = read_token(&p_text[pos], len - pos, line, advance);
471 t.line = line;
472 t.col = col;
473
474 if (t.type == TK_ERROR) {
475
476 if (r_error) {
477 *r_error = t.text;
478 *r_err_line = line;
479 *r_err_column = col;
480 return ERR_COMPILATION_FAILED;
481 }
482 }
483
484 if (line == prev_line) {
485 col += advance;
486 } else {
487 col = 0;
488 //p_tokens->push_back(Token(TK_LINE,itos(line)))
489 }
490
491 if (t.type != TK_EMPTY)
492 p_tokens->push_back(t);
493
494 pos += advance;
495 }
496
497 return OK;
498 }
499
lex_debug(const String & p_code)500 String ShaderLanguage::lex_debug(const String &p_code) {
501
502 Vector<Token> tokens;
503 String error;
504 int errline, errcol;
505 if (tokenize(p_code, &tokens, &error, &errline, &errcol) != OK)
506 return error;
507 String ret;
508 for (int i = 0; i < tokens.size(); i++) {
509 ret += String(token_names[tokens[i].type]) + ":" + itos(tokens[i].line) + ":" + itos(tokens[i].col) + ":" + tokens[i].text + "\n";
510 }
511
512 return ret;
513 }
514
is_token_datatype(TokenType p_type)515 bool ShaderLanguage::is_token_datatype(TokenType p_type) {
516
517 return (p_type == TK_TYPE_VOID) ||
518 (p_type == TK_TYPE_BOOL) ||
519 (p_type == TK_TYPE_FLOAT) ||
520 (p_type == TK_TYPE_VEC2) ||
521 (p_type == TK_TYPE_VEC3) ||
522 (p_type == TK_TYPE_VEC4) ||
523 (p_type == TK_TYPE_COLOR) ||
524 (p_type == TK_TYPE_MAT2) ||
525 (p_type == TK_TYPE_MAT3) ||
526 (p_type == TK_TYPE_MAT4) ||
527 (p_type == TK_TYPE_CUBEMAP) ||
528 (p_type == TK_TYPE_TEXTURE);
529 }
530
get_token_datatype(TokenType p_type)531 ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) {
532
533 switch (p_type) {
534
535 case TK_TYPE_VOID: return TYPE_VOID;
536 case TK_TYPE_BOOL: return TYPE_BOOL;
537 case TK_TYPE_FLOAT: return TYPE_FLOAT;
538 case TK_TYPE_VEC2: return TYPE_VEC2;
539 case TK_TYPE_VEC3: return TYPE_VEC3;
540 case TK_TYPE_VEC4: return TYPE_VEC4;
541 case TK_TYPE_COLOR: return TYPE_VEC4;
542 case TK_TYPE_MAT2: return TYPE_MAT2;
543 case TK_TYPE_MAT3: return TYPE_MAT3;
544 case TK_TYPE_MAT4: return TYPE_MAT4;
545 case TK_TYPE_TEXTURE: return TYPE_TEXTURE;
546 case TK_TYPE_CUBEMAP: return TYPE_CUBEMAP;
547 default: return TYPE_VOID;
548 }
549
550 return TYPE_VOID;
551 }
552
get_datatype_name(DataType p_type)553 String ShaderLanguage::get_datatype_name(DataType p_type) {
554
555 switch (p_type) {
556
557 case TYPE_VOID: return "void";
558 case TYPE_BOOL: return "bool";
559 case TYPE_FLOAT: return "float";
560 case TYPE_VEC2: return "vec2";
561 case TYPE_VEC3: return "vec3";
562 case TYPE_VEC4: return "vec4";
563 case TYPE_MAT2: return "mat2";
564 case TYPE_MAT3: return "mat3";
565 case TYPE_MAT4: return "mat4";
566 case TYPE_TEXTURE: return "texture";
567 case TYPE_CUBEMAP: return "cubemap";
568 default: return "";
569 }
570
571 return "";
572 }
573
is_token_nonvoid_datatype(TokenType p_type)574 bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) {
575
576 return (p_type == TK_TYPE_BOOL) ||
577 (p_type == TK_TYPE_FLOAT) ||
578 (p_type == TK_TYPE_VEC2) ||
579 (p_type == TK_TYPE_VEC3) ||
580 (p_type == TK_TYPE_VEC4) ||
581 (p_type == TK_TYPE_COLOR) ||
582 (p_type == TK_TYPE_MAT2) ||
583 (p_type == TK_TYPE_MAT3) ||
584 (p_type == TK_TYPE_MAT4) ||
585 (p_type == TK_TYPE_TEXTURE) ||
586 (p_type == TK_TYPE_CUBEMAP);
587 }
588
parser_is_at_function(Parser & parser)589 bool ShaderLanguage::parser_is_at_function(Parser &parser) {
590
591 return (is_token_datatype(parser.get_next_token_type(0)) && parser.get_next_token_type(1) == TK_INDENTIFIER && parser.get_next_token_type(2) == TK_PARENTHESIS_OPEN);
592 }
593
test_existing_identifier(Node * p_node,const StringName p_identifier,bool p_func,bool p_var,bool p_builtin)594 bool ShaderLanguage::test_existing_identifier(Node *p_node, const StringName p_identifier, bool p_func, bool p_var, bool p_builtin) {
595
596 Node *node = p_node;
597
598 while (node) {
599
600 if (node->type == Node::TYPE_BLOCK) {
601
602 BlockNode *block = (BlockNode *)node;
603 if (block->variables.has(p_identifier))
604 return true;
605 } else if (node->type == Node::TYPE_PROGRAM) {
606
607 ProgramNode *program = (ProgramNode *)node;
608 for (int i = 0; i < program->functions.size(); i++) {
609
610 if (program->functions[i].name == p_identifier) {
611 return true;
612 }
613 }
614
615 if (program->builtin_variables.has(p_identifier)) {
616 return true;
617 }
618 if (program->uniforms.has(p_identifier)) {
619 return true;
620 }
621
622 } else if (node->type == Node::TYPE_FUNCTION) {
623
624 FunctionNode *func = (FunctionNode *)node;
625 for (int i = 0; i < func->arguments.size(); i++)
626 if (func->arguments[i].name == p_identifier)
627 return true;
628 }
629
630 node = node->parent;
631 }
632
633 // try keywords
634
635 int idx = 0;
636
637 //todo optimize
638 while (intrinsic_func_defs[idx].name) {
639
640 if (p_identifier.operator String() == intrinsic_func_defs[idx].name)
641 return true;
642 idx++;
643 }
644
645 return false;
646 }
647
parse_function(Parser & parser,BlockNode * p_block)648 Error ShaderLanguage::parse_function(Parser &parser, BlockNode *p_block) {
649
650 if (!p_block->parent || p_block->parent->type != Node::TYPE_PROGRAM) {
651 parser.set_error("Misplaced function");
652 return ERR_PARSE_ERROR;
653 }
654
655 ProgramNode *program = (ProgramNode *)p_block->parent;
656
657 StringName name = parser.get_next_token(1).text;
658
659 if (test_existing_identifier(p_block, name)) {
660
661 parser.set_error("Duplicate Identifier (existing variable/builtin/function): " + name);
662 return ERR_PARSE_ERROR;
663 }
664
665 FunctionNode *function = parser.create_node<FunctionNode>(program);
666 function->body = parser.create_node<BlockNode>(function);
667
668 function->name = name;
669
670 function->return_type = get_token_datatype(parser.get_next_token_type(0));
671
672 { //add to programnode
673 ProgramNode::Function f;
674 f.name = name;
675 f.function = function;
676 program->functions.push_back(f);
677 }
678
679 int ofs = 3;
680
681 while (true) {
682
683 //end of arguments
684 if (parser.get_next_token_type(ofs) == TK_PARENTHESIS_CLOSE) {
685 ofs++;
686 break;
687 }
688 //next argument awaits
689 if (parser.get_next_token_type(ofs) == TK_COMMA) {
690 if (!is_token_nonvoid_datatype(parser.get_next_token_type(ofs + 1))) {
691 parser.set_error("Expected Identifier or ')' following ','");
692 return ERR_PARSE_ERROR;
693 }
694 ofs++;
695 continue;
696 }
697
698 if (!is_token_nonvoid_datatype(parser.get_next_token_type(ofs + 0))) {
699 parser.set_error("Invalid Argument Type");
700 return ERR_PARSE_ERROR;
701 }
702
703 DataType identtype = get_token_datatype(parser.get_next_token_type(ofs + 0));
704
705 if (parser.get_next_token_type(ofs + 1) != TK_INDENTIFIER) {
706 parser.set_error("Expected Argument Identifier");
707 return ERR_PARSE_ERROR;
708 }
709
710 StringName identname = parser.get_next_token(ofs + 1).text;
711
712 if (test_existing_identifier(function, identname)) {
713 parser.set_error("Duplicate Argument Identifier: " + identname);
714 return ERR_DUPLICATE_SYMBOL;
715 }
716
717 FunctionNode::Argument arg;
718 arg.name = identname;
719 arg.type = identtype;
720 //function->body->variables[arg.name]=arg.type;
721 function->arguments.push_back(arg);
722
723 ofs += 2;
724 }
725
726 parser.advance(ofs);
727 // match {
728 if (parser.get_next_token_type() != TK_CURLY_BRACKET_OPEN) {
729 parser.set_error("Expected '{'");
730 return ERR_PARSE_ERROR;
731 }
732
733 parser.advance();
734 Error err = parse_block(parser, function->body);
735
736 if (err)
737 return err;
738
739 // make sure that if the function has a return type, it does return something..
740 if (function->return_type != TYPE_VOID) {
741 bool found = false;
742 for (int i = 0; i < function->body->statements.size(); i++) {
743 if (function->body->statements[i]->type == Node::TYPE_CONTROL_FLOW) {
744
745 ControlFlowNode *cf = (ControlFlowNode *)function->body->statements[i];
746 if (cf->flow_op == FLOW_OP_RETURN) {
747 // type of return was already checked when inserted
748 // no need to check here
749 found = true;
750 }
751 }
752 }
753
754 if (!found) {
755 parser.set_error("Function must return a value (use the main block)");
756 return ERR_PARSE_ERROR;
757 }
758 }
759
760 return OK;
761 }
762
763 const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[] = {
764 //constructors
765 { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID } },
766 { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
767 { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_VOID } },
768 { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
769 { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VOID } },
770 { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
771 { "vec3", TYPE_VEC3, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
772 { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } },
773 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VOID } },
774 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
775 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
776 { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
777 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } },
778 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID } },
779 { "vec4", TYPE_VEC4, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
780 { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
781 { "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
782 { "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
783 { "mat4", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
784 //intrinsics - trigonometry
785 { "sin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
786 { "cos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
787 { "tan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
788 { "asin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
789 { "acos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
790 { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
791 { "atan2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
792 { "sinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
793 { "cosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
794 { "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
795 //intrinsics - exponential
796 { "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
797 { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
798 { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
799 { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
800 { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
801 { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
802 { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
803 { "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
804 { "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
805 { "exp", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
806 { "exp", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
807 { "log", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
808 { "log", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
809 { "log", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
810 { "log", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
811 { "sqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
812 { "sqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
813 { "sqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
814 { "sqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
815 //intrinsics - common
816 { "abs", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
817 { "abs", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
818 { "abs", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
819 { "abs", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
820 { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
821 { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
822 { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
823 { "sign", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
824 { "floor", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
825 { "floor", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
826 { "floor", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
827 { "floor", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
828 { "trunc", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
829 { "trunc", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
830 { "trunc", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
831 { "trunc", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
832 { "round", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
833 { "round", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
834 { "round", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
835 { "round", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
836 { "ceil", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
837 { "ceil", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
838 { "ceil", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
839 { "ceil", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
840 { "fract", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
841 { "fract", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
842 { "fract", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
843 { "fract", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
844 { "mod", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
845 { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
846 { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
847 { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
848 { "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
849 { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
850 { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
851 { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
852 { "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
853 { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
854 { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
855 { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
856 { "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
857 { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
858 { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
859 { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
860 { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
861 { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
862 { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
863 { "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
864 { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
865 { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
866 { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
867 { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
868 { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
869 { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
870 { "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
871 { "step", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
872 { "step", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
873 { "step", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
874 { "step", TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } },
875 { "step", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID } },
876 { "step", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4, TYPE_VOID } },
877 { "smoothstep", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
878 { "smoothstep", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
879 { "smoothstep", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
880 { "smoothstep", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
881 { "smoothstep", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } },
882 { "smoothstep", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC3, TYPE_VOID } },
883 { "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID } },
884
885 //intrinsics - geometric
886 { "length", TYPE_FLOAT, { TYPE_VEC2, TYPE_VOID } },
887 { "length", TYPE_FLOAT, { TYPE_VEC3, TYPE_VOID } },
888 { "length", TYPE_FLOAT, { TYPE_VEC4, TYPE_VOID } },
889 { "distance", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
890 { "distance", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
891 { "distance", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
892 { "dot", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
893 { "dot", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
894 { "dot", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
895 { "cross", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
896 { "normalize", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
897 { "normalize", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
898 { "normalize", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
899 { "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
900 { "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
901 //intrinsics - texture
902 { "tex", TYPE_VEC4, { TYPE_TEXTURE, TYPE_VEC2, TYPE_VOID } },
903 { "texcube", TYPE_VEC4, { TYPE_CUBEMAP, TYPE_VEC3, TYPE_VOID } },
904 { "texscreen", TYPE_VEC3, { TYPE_VEC2, TYPE_VOID } },
905 { "texpos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
906
907 { NULL, TYPE_VOID, { TYPE_VOID } }
908
909 };
910
911 const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[] = {
912
913 { OP_ASSIGN, TYPE_VOID, { TYPE_BOOL, TYPE_BOOL } },
914 { OP_ASSIGN, TYPE_VOID, { TYPE_FLOAT, TYPE_FLOAT } },
915 { OP_ASSIGN, TYPE_VOID, { TYPE_VEC2, TYPE_VEC2 } },
916 { OP_ASSIGN, TYPE_VOID, { TYPE_VEC3, TYPE_VEC3 } },
917 { OP_ASSIGN, TYPE_VOID, { TYPE_VEC4, TYPE_VEC4 } },
918 { OP_ASSIGN, TYPE_VOID, { TYPE_MAT2, TYPE_MAT2 } },
919 { OP_ASSIGN, TYPE_VOID, { TYPE_MAT3, TYPE_MAT3 } },
920 { OP_ASSIGN, TYPE_VOID, { TYPE_MAT4, TYPE_MAT4 } },
921 { OP_ADD, TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT } },
922 { OP_ADD, TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2 } },
923 { OP_ADD, TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3 } },
924 { OP_ADD, TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4 } },
925 { OP_SUB, TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT } },
926 { OP_SUB, TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2 } },
927 { OP_SUB, TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3 } },
928 { OP_SUB, TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4 } },
929 { OP_MUL, TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT } },
930 { OP_MUL, TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2 } },
931 { OP_MUL, TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT } },
932 { OP_MUL, TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2 } },
933 { OP_MUL, TYPE_VEC2, { TYPE_VEC2, TYPE_MAT3 } },
934 { OP_MUL, TYPE_VEC2, { TYPE_MAT2, TYPE_VEC2 } },
935 { OP_MUL, TYPE_VEC2, { TYPE_VEC2, TYPE_MAT2 } },
936 { OP_MUL, TYPE_VEC2, { TYPE_MAT3, TYPE_VEC2 } },
937 { OP_MUL, TYPE_VEC2, { TYPE_VEC2, TYPE_MAT4 } },
938 { OP_MUL, TYPE_VEC2, { TYPE_MAT4, TYPE_VEC2 } },
939 { OP_MUL, TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3 } },
940 { OP_MUL, TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT } },
941 { OP_MUL, TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3 } },
942 { OP_MUL, TYPE_VEC3, { TYPE_MAT3, TYPE_VEC3 } },
943 { OP_MUL, TYPE_VEC3, { TYPE_MAT4, TYPE_VEC3 } },
944 { OP_MUL, TYPE_VEC3, { TYPE_VEC3, TYPE_MAT3 } },
945 { OP_MUL, TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4 } },
946 { OP_MUL, TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT } },
947 { OP_MUL, TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4 } },
948 { OP_MUL, TYPE_VEC4, { TYPE_MAT4, TYPE_VEC4 } },
949 { OP_MUL, TYPE_VEC4, { TYPE_VEC4, TYPE_MAT4 } },
950 { OP_MUL, TYPE_MAT2, { TYPE_MAT2, TYPE_MAT2 } },
951 { OP_MUL, TYPE_MAT3, { TYPE_MAT3, TYPE_MAT3 } },
952 { OP_MUL, TYPE_MAT4, { TYPE_MAT4, TYPE_MAT4 } },
953 { OP_DIV, TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT } },
954 { OP_DIV, TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2 } },
955 { OP_DIV, TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT } },
956 { OP_DIV, TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2 } },
957 { OP_DIV, TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3 } },
958 { OP_DIV, TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT } },
959 { OP_DIV, TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3 } },
960 { OP_DIV, TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4 } },
961 { OP_DIV, TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT } },
962 { OP_DIV, TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4 } },
963 { OP_ASSIGN_ADD, TYPE_VOID, { TYPE_FLOAT, TYPE_FLOAT } },
964 { OP_ASSIGN_ADD, TYPE_VOID, { TYPE_VEC2, TYPE_VEC2 } },
965 { OP_ASSIGN_ADD, TYPE_VOID, { TYPE_VEC3, TYPE_VEC3 } },
966 { OP_ASSIGN_ADD, TYPE_VOID, { TYPE_VEC4, TYPE_VEC4 } },
967 { OP_ASSIGN_ADD, TYPE_VOID, { TYPE_VEC2, TYPE_FLOAT } },
968 { OP_ASSIGN_ADD, TYPE_VOID, { TYPE_VEC3, TYPE_FLOAT } },
969 { OP_ASSIGN_ADD, TYPE_VOID, { TYPE_VEC4, TYPE_FLOAT } },
970 { OP_ASSIGN_SUB, TYPE_VOID, { TYPE_FLOAT, TYPE_FLOAT } },
971 { OP_ASSIGN_SUB, TYPE_VOID, { TYPE_VEC2, TYPE_VEC2 } },
972 { OP_ASSIGN_SUB, TYPE_VOID, { TYPE_VEC3, TYPE_VEC3 } },
973 { OP_ASSIGN_SUB, TYPE_VOID, { TYPE_VEC4, TYPE_VEC4 } },
974 { OP_ASSIGN_SUB, TYPE_VOID, { TYPE_VEC2, TYPE_FLOAT } },
975 { OP_ASSIGN_SUB, TYPE_VOID, { TYPE_VEC3, TYPE_FLOAT } },
976 { OP_ASSIGN_SUB, TYPE_VOID, { TYPE_VEC4, TYPE_FLOAT } },
977 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_FLOAT, TYPE_FLOAT } },
978 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC2, TYPE_VEC2 } },
979 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC2, TYPE_FLOAT } },
980 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC2, TYPE_MAT2 } },
981 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_MAT2, TYPE_MAT2 } },
982 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC3, TYPE_MAT3 } },
983 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC3, TYPE_VEC3 } },
984 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC3, TYPE_FLOAT } },
985 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC3, TYPE_MAT4 } },
986 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC4, TYPE_VEC4 } },
987 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC4, TYPE_FLOAT } },
988 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_VEC4, TYPE_MAT4 } },
989 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_MAT3, TYPE_MAT3 } },
990 { OP_ASSIGN_MUL, TYPE_VOID, { TYPE_MAT4, TYPE_MAT4 } },
991 { OP_ASSIGN_DIV, TYPE_VOID, { TYPE_FLOAT, TYPE_FLOAT } },
992 { OP_ASSIGN_DIV, TYPE_VOID, { TYPE_VEC2, TYPE_VEC2 } },
993 { OP_ASSIGN_DIV, TYPE_VOID, { TYPE_VEC2, TYPE_FLOAT } },
994 { OP_ASSIGN_DIV, TYPE_VOID, { TYPE_VEC3, TYPE_VEC3 } },
995 { OP_ASSIGN_DIV, TYPE_VOID, { TYPE_VEC3, TYPE_FLOAT } },
996 { OP_ASSIGN_DIV, TYPE_VOID, { TYPE_VEC4, TYPE_VEC4 } },
997 { OP_ASSIGN_DIV, TYPE_VOID, { TYPE_VEC4, TYPE_FLOAT } },
998 { OP_NEG, TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
999 { OP_NEG, TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
1000 { OP_NEG, TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } },
1001 { OP_NEG, TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } },
1002 { OP_NOT, TYPE_BOOL, { TYPE_BOOL, TYPE_VOID } },
1003 { OP_CMP_EQ, TYPE_BOOL, { TYPE_BOOL, TYPE_BOOL } },
1004 { OP_CMP_EQ, TYPE_BOOL, { TYPE_FLOAT, TYPE_FLOAT } },
1005 { OP_CMP_EQ, TYPE_BOOL, { TYPE_VEC3, TYPE_VEC2 } },
1006 { OP_CMP_EQ, TYPE_BOOL, { TYPE_VEC3, TYPE_VEC3 } },
1007 { OP_CMP_EQ, TYPE_BOOL, { TYPE_VEC3, TYPE_VEC4 } },
1008 //{OP_CMP_EQ,TYPE_MAT3,{TYPE_MAT4,TYPE_MAT3}}, ??
1009 //{OP_CMP_EQ,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}}, ??
1010 { OP_CMP_NEQ, TYPE_BOOL, { TYPE_BOOL, TYPE_BOOL } },
1011 { OP_CMP_NEQ, TYPE_BOOL, { TYPE_FLOAT, TYPE_FLOAT } },
1012 { OP_CMP_NEQ, TYPE_BOOL, { TYPE_VEC2, TYPE_VEC2 } },
1013 { OP_CMP_NEQ, TYPE_BOOL, { TYPE_VEC3, TYPE_VEC3 } },
1014 { OP_CMP_NEQ, TYPE_BOOL, { TYPE_VEC4, TYPE_VEC4 } },
1015 //{OP_CMP_NEQ,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}}, //?
1016 { OP_CMP_LEQ, TYPE_BOOL, { TYPE_FLOAT, TYPE_FLOAT } },
1017 { OP_CMP_GEQ, TYPE_BOOL, { TYPE_FLOAT, TYPE_FLOAT } },
1018 { OP_CMP_LESS, TYPE_BOOL, { TYPE_FLOAT, TYPE_FLOAT } },
1019 { OP_CMP_GREATER, TYPE_BOOL, { TYPE_FLOAT, TYPE_FLOAT } },
1020 { OP_CMP_OR, TYPE_BOOL, { TYPE_BOOL, TYPE_BOOL } },
1021 { OP_CMP_AND, TYPE_BOOL, { TYPE_BOOL, TYPE_BOOL } },
1022 { OP_MAX, TYPE_VOID, { TYPE_VOID, TYPE_VOID } }
1023 };
1024
1025 const ShaderLanguage::BuiltinsDef ShaderLanguage::vertex_builtins_defs[] = {
1026
1027 { "SRC_VERTEX", TYPE_VEC3 },
1028 { "SRC_NORMAL", TYPE_VEC3 },
1029 { "SRC_TANGENT", TYPE_VEC3 },
1030 { "SRC_BINORMALF", TYPE_FLOAT },
1031
1032 { "POSITION", TYPE_VEC4 },
1033 { "VERTEX", TYPE_VEC3 },
1034 { "NORMAL", TYPE_VEC3 },
1035 { "TANGENT", TYPE_VEC3 },
1036 { "BINORMAL", TYPE_VEC3 },
1037 { "UV", TYPE_VEC2 },
1038 { "UV2", TYPE_VEC2 },
1039 { "COLOR", TYPE_VEC4 },
1040 { "BONES", TYPE_VEC4 },
1041 { "WEIGHTS", TYPE_VEC4 },
1042 { "VAR1", TYPE_VEC4 },
1043 { "VAR2", TYPE_VEC4 },
1044 { "SPEC_EXP", TYPE_FLOAT },
1045 { "POINT_SIZE", TYPE_FLOAT },
1046
1047 //builtins
1048 { "WORLD_MATRIX", TYPE_MAT4 },
1049 { "INV_CAMERA_MATRIX", TYPE_MAT4 },
1050 { "PROJECTION_MATRIX", TYPE_MAT4 },
1051 { "MODELVIEW_MATRIX", TYPE_MAT4 },
1052 { "INSTANCE_ID", TYPE_FLOAT },
1053 { "TIME", TYPE_FLOAT },
1054 { NULL, TYPE_VOID },
1055 };
1056 const ShaderLanguage::BuiltinsDef ShaderLanguage::fragment_builtins_defs[] = {
1057
1058 { "VERTEX", TYPE_VEC3 },
1059 { "POSITION", TYPE_VEC4 },
1060 { "NORMAL", TYPE_VEC3 },
1061 { "TANGENT", TYPE_VEC3 },
1062 { "BINORMAL", TYPE_VEC3 },
1063 { "NORMALMAP", TYPE_VEC3 },
1064 { "NORMALMAP_DEPTH", TYPE_FLOAT },
1065 { "UV", TYPE_VEC2 },
1066 { "UV2", TYPE_VEC2 },
1067 { "COLOR", TYPE_VEC4 },
1068 { "NORMAL", TYPE_VEC3 },
1069 { "VAR1", TYPE_VEC4 },
1070 { "VAR2", TYPE_VEC4 },
1071 { "DIFFUSE", TYPE_VEC3 },
1072 { "DIFFUSE_ALPHA", TYPE_VEC4 },
1073 { "SPECULAR", TYPE_VEC3 },
1074 { "EMISSION", TYPE_VEC3 },
1075 { "SPEC_EXP", TYPE_FLOAT },
1076 { "GLOW", TYPE_FLOAT },
1077 { "SHADE_PARAM", TYPE_FLOAT },
1078 { "DISCARD", TYPE_BOOL },
1079 { "SCREEN_UV", TYPE_VEC2 },
1080 { "POINT_COORD", TYPE_VEC2 },
1081 { "INV_CAMERA_MATRIX", TYPE_MAT4 },
1082
1083 // { "SCREEN_POS", TYPE_VEC2},
1084 // { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
1085 { "TIME", TYPE_FLOAT },
1086 { NULL, TYPE_VOID }
1087
1088 };
1089
1090 const ShaderLanguage::BuiltinsDef ShaderLanguage::light_builtins_defs[] = {
1091
1092 { "NORMAL", TYPE_VEC3 },
1093 { "LIGHT_DIR", TYPE_VEC3 },
1094 { "LIGHT_DIFFUSE", TYPE_VEC3 },
1095 { "LIGHT_SPECULAR", TYPE_VEC3 },
1096 { "EYE_VEC", TYPE_VEC3 },
1097 { "DIFFUSE", TYPE_VEC3 },
1098 { "SPECULAR", TYPE_VEC3 },
1099 { "SPECULAR_EXP", TYPE_FLOAT },
1100 { "SHADE_PARAM", TYPE_FLOAT },
1101 { "LIGHT", TYPE_VEC3 },
1102 { "SHADOW", TYPE_VEC3 },
1103 { "POINT_COORD", TYPE_VEC2 },
1104 // { "SCREEN_POS", TYPE_VEC2},
1105 // { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
1106 { "TIME", TYPE_FLOAT },
1107 { NULL, TYPE_VOID }
1108
1109 };
1110
1111 const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_vertex_builtins_defs[] = {
1112
1113 { "SRC_VERTEX", TYPE_VEC2 },
1114 { "VERTEX", TYPE_VEC2 },
1115 { "WORLD_VERTEX", TYPE_VEC2 },
1116 { "UV", TYPE_VEC2 },
1117 { "COLOR", TYPE_VEC4 },
1118 { "VAR1", TYPE_VEC4 },
1119 { "VAR2", TYPE_VEC4 },
1120 { "POINT_SIZE", TYPE_FLOAT },
1121
1122 //builtins
1123 { "WORLD_MATRIX", TYPE_MAT4 },
1124 { "PROJECTION_MATRIX", TYPE_MAT4 },
1125 { "EXTRA_MATRIX", TYPE_MAT4 },
1126 { "TIME", TYPE_FLOAT },
1127 { "AT_LIGHT_PASS", TYPE_BOOL },
1128 { NULL, TYPE_VOID },
1129 };
1130 const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[] = {
1131
1132 { "SRC_COLOR", TYPE_VEC4 },
1133 { "POSITION", TYPE_VEC2 },
1134 { "NORMAL", TYPE_VEC3 },
1135 { "NORMALMAP", TYPE_VEC3 },
1136 { "NORMALMAP_DEPTH", TYPE_FLOAT },
1137 { "UV", TYPE_VEC2 },
1138 { "COLOR", TYPE_VEC4 },
1139 { "TEXTURE", TYPE_TEXTURE },
1140 { "TEXTURE_PIXEL_SIZE", TYPE_VEC2 },
1141 { "VAR1", TYPE_VEC4 },
1142 { "VAR2", TYPE_VEC4 },
1143 { "SCREEN_UV", TYPE_VEC2 },
1144 { "POINT_COORD", TYPE_VEC2 },
1145
1146 // { "SCREEN_POS", TYPE_VEC2},
1147 // { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
1148 { "TIME", TYPE_FLOAT },
1149 { "AT_LIGHT_PASS", TYPE_BOOL },
1150 { NULL, TYPE_VOID }
1151
1152 };
1153
1154 const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[] = {
1155
1156 { "POSITION", TYPE_VEC2 },
1157 { "NORMAL", TYPE_VEC3 },
1158 { "UV", TYPE_VEC2 },
1159 { "COLOR", TYPE_VEC4 },
1160 { "TEXTURE", TYPE_TEXTURE },
1161 { "TEXTURE_PIXEL_SIZE", TYPE_VEC2 },
1162 { "VAR1", TYPE_VEC4 },
1163 { "VAR2", TYPE_VEC4 },
1164 { "SCREEN_UV", TYPE_VEC2 },
1165 { "LIGHT_VEC", TYPE_VEC2 },
1166 { "LIGHT_HEIGHT", TYPE_FLOAT },
1167 { "LIGHT_COLOR", TYPE_VEC4 },
1168 { "LIGHT_UV", TYPE_VEC2 },
1169 { "LIGHT_SHADOW", TYPE_VEC4 },
1170 { "LIGHT", TYPE_VEC4 },
1171 { "SHADOW", TYPE_VEC4 },
1172 { "POINT_COORD", TYPE_VEC2 },
1173 // { "SCREEN_POS", TYPE_VEC2},
1174 // { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
1175 { "TIME", TYPE_FLOAT },
1176 { NULL, TYPE_VOID }
1177
1178 };
1179
1180 const ShaderLanguage::BuiltinsDef ShaderLanguage::postprocess_fragment_builtins_defs[] = {
1181
1182 { "IN_COLOR", TYPE_VEC3 },
1183 { "IN_POSITION", TYPE_VEC3 },
1184 { "OUT_COLOR", TYPE_VEC3 },
1185 { "SCREEN_POS", TYPE_VEC2 },
1186 { "SCREEN_TEXEL_SIZE", TYPE_VEC2 },
1187 { "TIME", TYPE_FLOAT },
1188 { NULL, TYPE_VOID }
1189 };
1190
compute_node_type(Node * p_node)1191 ShaderLanguage::DataType ShaderLanguage::compute_node_type(Node *p_node) {
1192
1193 switch (p_node->type) {
1194
1195 case Node::TYPE_PROGRAM: ERR_FAIL_V(TYPE_VOID);
1196 case Node::TYPE_FUNCTION: return static_cast<FunctionNode *>(p_node)->return_type;
1197 case Node::TYPE_BLOCK: ERR_FAIL_V(TYPE_VOID);
1198 case Node::TYPE_VARIABLE: return static_cast<VariableNode *>(p_node)->datatype_cache;
1199 case Node::TYPE_CONSTANT: return static_cast<ConstantNode *>(p_node)->datatype;
1200 case Node::TYPE_OPERATOR: return static_cast<OperatorNode *>(p_node)->return_cache;
1201 case Node::TYPE_CONTROL_FLOW: ERR_FAIL_V(TYPE_VOID);
1202 case Node::TYPE_MEMBER: return static_cast<MemberNode *>(p_node)->datatype;
1203 }
1204
1205 return TYPE_VOID;
1206 }
1207
validate_function_call(Parser & parser,OperatorNode * p_func)1208 ShaderLanguage::Node *ShaderLanguage::validate_function_call(Parser &parser, OperatorNode *p_func) {
1209
1210 ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, NULL);
1211
1212 Vector<DataType> args;
1213
1214 ERR_FAIL_COND_V(p_func->arguments[0]->type != Node::TYPE_VARIABLE, NULL);
1215
1216 String name = static_cast<VariableNode *>(p_func->arguments[0])->name.operator String();
1217
1218 bool all_const = true;
1219 for (int i = 1; i < p_func->arguments.size(); i++) {
1220 if (p_func->arguments[i]->type != Node::TYPE_CONSTANT)
1221 all_const = false;
1222 args.push_back(compute_node_type(p_func->arguments[i]));
1223 }
1224
1225 int argcount = args.size();
1226
1227 bool found_intrinsic = false;
1228
1229 if (argcount <= 4) {
1230 // test intrinsics
1231 int idx = 0;
1232
1233 while (intrinsic_func_defs[idx].name) {
1234
1235 if (name == intrinsic_func_defs[idx].name) {
1236
1237 bool fail = false;
1238 for (int i = 0; i < argcount; i++) {
1239
1240 if (args[i] != intrinsic_func_defs[idx].args[i]) {
1241 fail = true;
1242 break;
1243 }
1244 }
1245
1246 if (!fail && argcount < 4 && intrinsic_func_defs[idx].args[argcount] != TYPE_VOID)
1247 fail = true; //make sure the number of arguments matches
1248
1249 if (!fail) {
1250 p_func->return_cache = intrinsic_func_defs[idx].rettype;
1251 found_intrinsic = true;
1252 break;
1253 }
1254 }
1255
1256 idx++;
1257 }
1258 }
1259
1260 if (found_intrinsic) {
1261
1262 if (p_func->op == OP_CONSTRUCT && all_const) {
1263
1264 Vector<float> cdata;
1265 for (int i = 0; i < argcount; i++) {
1266
1267 Variant v = static_cast<ConstantNode *>(p_func->arguments[i + 1])->value;
1268 switch (v.get_type()) {
1269
1270 case Variant::REAL: cdata.push_back(v); break;
1271 case Variant::VECTOR2: {
1272 Vector2 v2 = v;
1273 cdata.push_back(v2.x);
1274 cdata.push_back(v2.y);
1275 } break;
1276 case Variant::VECTOR3: {
1277 Vector3 v3 = v;
1278 cdata.push_back(v3.x);
1279 cdata.push_back(v3.y);
1280 cdata.push_back(v3.z);
1281 } break;
1282 case Variant::PLANE: {
1283 Plane v4 = v;
1284 cdata.push_back(v4.normal.x);
1285 cdata.push_back(v4.normal.y);
1286 cdata.push_back(v4.normal.z);
1287 cdata.push_back(v4.d);
1288 } break;
1289 default: ERR_FAIL_V(NULL);
1290 }
1291 }
1292
1293 ConstantNode *cn = parser.create_node<ConstantNode>(p_func->parent);
1294 Variant data;
1295 switch (p_func->return_cache) {
1296 case TYPE_FLOAT: data = cdata[0]; break;
1297 case TYPE_VEC2:
1298 if (cdata.size() == 1)
1299 data = Vector2(cdata[0], cdata[0]);
1300 else
1301 data = Vector2(cdata[0], cdata[1]);
1302
1303 break;
1304 case TYPE_VEC3:
1305 if (cdata.size() == 1)
1306 data = Vector3(cdata[0], cdata[0], cdata[0]);
1307 else
1308 data = Vector3(cdata[0], cdata[1], cdata[2]);
1309 break;
1310 case TYPE_VEC4:
1311 if (cdata.size() == 1)
1312 data = Plane(cdata[0], cdata[0], cdata[0], cdata[0]);
1313 else
1314 data = Plane(cdata[0], cdata[1], cdata[2], cdata[3]);
1315 break;
1316 }
1317
1318 cn->datatype = p_func->return_cache;
1319 cn->value = data;
1320 return cn;
1321 }
1322 return p_func;
1323 }
1324
1325 // try existing functions..
1326
1327 FunctionNode *exclude_function = NULL; //exclude current function (in case inside one)
1328
1329 Node *node = p_func;
1330
1331 while (node->parent) {
1332
1333 if (node->type == Node::TYPE_FUNCTION) {
1334
1335 exclude_function = (FunctionNode *)node;
1336 }
1337
1338 node = node->parent;
1339 }
1340
1341 ERR_FAIL_COND_V(node->type != Node::TYPE_PROGRAM, NULL);
1342 ProgramNode *program = (ProgramNode *)node;
1343
1344 for (int i = 0; i < program->functions.size(); i++) {
1345
1346 if (program->functions[i].function == exclude_function)
1347 continue;
1348
1349 FunctionNode *pfunc = program->functions[i].function;
1350
1351 if (pfunc->arguments.size() != args.size())
1352 continue;
1353
1354 bool fail = false;
1355
1356 for (int i = 0; i < args.size(); i++) {
1357 if (args[i] != pfunc->arguments[i].type) {
1358 fail = true;
1359 break;
1360 }
1361 }
1362
1363 if (!fail && name == program->functions[i].name) {
1364 p_func->return_cache = pfunc->return_type;
1365 return p_func;
1366 }
1367 }
1368
1369 return NULL;
1370 }
1371
validate_operator(Parser & parser,OperatorNode * p_func)1372 ShaderLanguage::Node *ShaderLanguage::validate_operator(Parser &parser, OperatorNode *p_func) {
1373
1374 int argcount = p_func->arguments.size();
1375 ERR_FAIL_COND_V(argcount > 2, NULL);
1376
1377 DataType argtype[2] = { TYPE_VOID, TYPE_VOID };
1378 bool all_const = true;
1379
1380 for (int i = 0; i < argcount; i++) {
1381
1382 argtype[i] = compute_node_type(p_func->arguments[i]);
1383 if (p_func->arguments[i]->type != Node::TYPE_CONSTANT)
1384 all_const = false;
1385 }
1386 int idx = 0;
1387
1388 bool valid = false;
1389 while (operator_defs[idx].op != OP_MAX) {
1390
1391 if (p_func->op == operator_defs[idx].op) {
1392
1393 if (operator_defs[idx].args[0] == argtype[0] && operator_defs[idx].args[1] == argtype[1]) {
1394
1395 p_func->return_cache = operator_defs[idx].rettype;
1396 valid = true;
1397 break;
1398 }
1399 }
1400
1401 idx++;
1402 }
1403
1404 if (!valid)
1405 return NULL;
1406
1407 #define _RCO2(m_op, m_vop) \
1408 case m_op: { \
1409 ConstantNode *cn = parser.create_node<ConstantNode>(p_func->parent); \
1410 cn->datatype = p_func->return_cache; \
1411 Variant::evaluate(m_vop, static_cast<ConstantNode *>(p_func->arguments[0])->value, static_cast<ConstantNode *>(p_func->arguments[1])->value, cn->value, valid); \
1412 if (!valid) \
1413 return NULL; \
1414 return cn; \
1415 } break;
1416
1417 #define _RCO1(m_op, m_vop) \
1418 case m_op: { \
1419 ConstantNode *cn = parser.create_node<ConstantNode>(p_func->parent); \
1420 cn->datatype = p_func->return_cache; \
1421 Variant::evaluate(m_vop, static_cast<ConstantNode *>(p_func->arguments[0])->value, Variant(), cn->value, valid); \
1422 if (!valid) \
1423 return NULL; \
1424 return cn; \
1425 } break;
1426
1427 if (all_const) {
1428 //reduce constant operator
1429 switch (p_func->op) {
1430 _RCO2(OP_ADD, Variant::OP_ADD);
1431 _RCO2(OP_SUB, Variant::OP_SUBSTRACT);
1432 _RCO2(OP_MUL, Variant::OP_MULTIPLY);
1433 _RCO2(OP_DIV, Variant::OP_DIVIDE);
1434 _RCO1(OP_NEG, Variant::OP_NEGATE);
1435 _RCO1(OP_NOT, Variant::OP_NOT);
1436 _RCO2(OP_CMP_EQ, Variant::OP_EQUAL);
1437 _RCO2(OP_CMP_NEQ, Variant::OP_NOT_EQUAL);
1438 _RCO2(OP_CMP_LEQ, Variant::OP_LESS_EQUAL);
1439 _RCO2(OP_CMP_GEQ, Variant::OP_GREATER_EQUAL);
1440 _RCO2(OP_CMP_LESS, Variant::OP_LESS);
1441 _RCO2(OP_CMP_GREATER, Variant::OP_GREATER);
1442 _RCO2(OP_CMP_OR, Variant::OP_OR);
1443 _RCO2(OP_CMP_AND, Variant::OP_AND);
1444 default: {}
1445 }
1446 }
1447
1448 return p_func;
1449 }
1450
is_token_operator(TokenType p_type)1451 bool ShaderLanguage::is_token_operator(TokenType p_type) {
1452
1453 return (p_type == TK_OP_EQUAL) ||
1454 (p_type == TK_OP_NOT_EQUAL) ||
1455 (p_type == TK_OP_LESS) ||
1456 (p_type == TK_OP_LESS_EQUAL) ||
1457 (p_type == TK_OP_GREATER) ||
1458 (p_type == TK_OP_GREATER_EQUAL) ||
1459 (p_type == TK_OP_AND) ||
1460 (p_type == TK_OP_OR) ||
1461 (p_type == TK_OP_NOT) ||
1462 (p_type == TK_OP_ADD) ||
1463 (p_type == TK_OP_SUB) ||
1464 (p_type == TK_OP_MUL) ||
1465 (p_type == TK_OP_DIV) ||
1466 (p_type == TK_OP_NEG) ||
1467 (p_type == TK_OP_ASSIGN) ||
1468 (p_type == TK_OP_ASSIGN_ADD) ||
1469 (p_type == TK_OP_ASSIGN_SUB) ||
1470 (p_type == TK_OP_ASSIGN_MUL) ||
1471 (p_type == TK_OP_ASSIGN_DIV);
1472 }
get_token_operator(TokenType p_type)1473 ShaderLanguage::Operator ShaderLanguage::get_token_operator(TokenType p_type) {
1474
1475 switch (p_type) {
1476 case TK_OP_EQUAL: return OP_CMP_EQ;
1477 case TK_OP_NOT_EQUAL: return OP_CMP_NEQ;
1478 case TK_OP_LESS: return OP_CMP_LESS;
1479 case TK_OP_LESS_EQUAL: return OP_CMP_LEQ;
1480 case TK_OP_GREATER: return OP_CMP_GREATER;
1481 case TK_OP_GREATER_EQUAL: return OP_CMP_GEQ;
1482 case TK_OP_AND: return OP_CMP_AND;
1483 case TK_OP_OR: return OP_CMP_OR;
1484 case TK_OP_NOT: return OP_NOT;
1485 case TK_OP_ADD: return OP_ADD;
1486 case TK_OP_SUB: return OP_SUB;
1487 case TK_OP_MUL: return OP_MUL;
1488 case TK_OP_DIV: return OP_DIV;
1489 case TK_OP_NEG: return OP_NEG;
1490 case TK_OP_ASSIGN: return OP_ASSIGN;
1491 case TK_OP_ASSIGN_ADD: return OP_ASSIGN_ADD;
1492 case TK_OP_ASSIGN_SUB: return OP_ASSIGN_SUB;
1493 case TK_OP_ASSIGN_MUL: return OP_ASSIGN_MUL;
1494 case TK_OP_ASSIGN_DIV: return OP_ASSIGN_DIV;
1495 default: ERR_FAIL_V(OP_MAX);
1496 }
1497
1498 return OP_MAX;
1499 }
1500
parse_expression(Parser & parser,Node * p_parent,Node ** r_expr)1501 Error ShaderLanguage::parse_expression(Parser &parser, Node *p_parent, Node **r_expr) {
1502
1503 Vector<Expression> expression;
1504 //Vector<TokenType> operators;
1505
1506 while (true) {
1507
1508 Node *expr = NULL;
1509
1510 if (parser.get_next_token_type() == TK_PARENTHESIS_OPEN) {
1511 //handle subexpression
1512 parser.advance();
1513 Error err = parse_expression(parser, p_parent, &expr);
1514 if (err)
1515 return err;
1516
1517 if (parser.get_next_token_type() != TK_PARENTHESIS_CLOSE) {
1518
1519 parser.set_error("Expected ')' in expression");
1520 return ERR_PARSE_ERROR;
1521 }
1522
1523 parser.advance();
1524
1525 } else if (parser.get_next_token_type() == TK_REAL_CONSTANT) {
1526
1527 ConstantNode *constant = parser.create_node<ConstantNode>(p_parent);
1528 constant->value = parser.get_next_token().text.operator String().to_double();
1529 constant->datatype = TYPE_FLOAT;
1530 expr = constant;
1531 parser.advance();
1532 } else if (parser.get_next_token_type() == TK_TRUE) {
1533 //print_line("found true");
1534
1535 //handle true constant
1536 ConstantNode *constant = parser.create_node<ConstantNode>(p_parent);
1537 constant->value = true;
1538 constant->datatype = TYPE_BOOL;
1539 expr = constant;
1540 parser.advance();
1541 } else if (parser.get_next_token_type() == TK_FALSE) {
1542
1543 //handle false constant
1544 ConstantNode *constant = parser.create_node<ConstantNode>(p_parent);
1545 constant->value = false;
1546 constant->datatype = TYPE_BOOL;
1547 expr = constant;
1548 parser.advance();
1549 } else if (parser.get_next_token_type() == TK_TYPE_VOID) {
1550
1551 //make sure void is not used in expression
1552 parser.set_error("Void value not allowed in Expression");
1553 return ERR_PARSE_ERROR;
1554 } else if (parser.get_next_token_type(1) == TK_PARENTHESIS_OPEN && (is_token_nonvoid_datatype(parser.get_next_token_type()) || parser.get_next_token_type() == TK_INDENTIFIER)) {
1555
1556 //function or constructor
1557 StringName name;
1558 DataType constructor = TYPE_VOID;
1559 if (is_token_nonvoid_datatype(parser.get_next_token_type())) {
1560
1561 constructor = get_token_datatype(parser.get_next_token_type());
1562 switch (get_token_datatype(parser.get_next_token_type())) {
1563 case TYPE_BOOL: name = "bool"; break;
1564 case TYPE_FLOAT: name = "float"; break;
1565 case TYPE_VEC2: name = "vec2"; break;
1566 case TYPE_VEC3: name = "vec3"; break;
1567 case TYPE_VEC4: name = "vec4"; break;
1568 case TYPE_MAT2: name = "mat2"; break;
1569 case TYPE_MAT3: name = "mat3"; break;
1570 case TYPE_MAT4: name = "mat4"; break;
1571 default: ERR_FAIL_V(ERR_BUG);
1572 }
1573 } else {
1574
1575 name = parser.get_next_token().text;
1576 }
1577
1578 if (!test_existing_identifier(p_parent, name)) {
1579
1580 parser.set_error("Unknown identifier in expression: " + name);
1581 return ERR_PARSE_ERROR;
1582 }
1583
1584 parser.advance(2);
1585
1586 OperatorNode *func = parser.create_node<OperatorNode>(p_parent);
1587
1588 func->op = constructor != TYPE_VOID ? OP_CONSTRUCT : OP_CALL;
1589
1590 VariableNode *funcname = parser.create_node<VariableNode>(func);
1591 funcname->name = name;
1592 func->arguments.push_back(funcname);
1593
1594 //parse parameters
1595
1596 if (parser.get_next_token_type() == TK_PARENTHESIS_CLOSE) {
1597 parser.advance();
1598 } else {
1599
1600 while (true) {
1601
1602 Node *arg = NULL;
1603 Error err = parse_expression(parser, func, &arg);
1604 if (err)
1605 return err;
1606 func->arguments.push_back(arg);
1607
1608 if (parser.get_next_token_type() == TK_PARENTHESIS_CLOSE) {
1609 parser.advance();
1610 break;
1611
1612 } else if (parser.get_next_token_type() == TK_COMMA) {
1613
1614 if (parser.get_next_token_type(1) == TK_PARENTHESIS_CLOSE) {
1615
1616 parser.set_error("Expression expected");
1617 return ERR_PARSE_ERROR;
1618 }
1619
1620 parser.advance();
1621 } else {
1622 // something is broken
1623 parser.set_error("Expected ',' or ')'");
1624 return ERR_PARSE_ERROR;
1625 }
1626 }
1627 }
1628
1629 expr = validate_function_call(parser, func);
1630 if (!expr) {
1631
1632 parser.set_error("Invalid arguments to function/constructor: " + StringName(name));
1633 return ERR_PARSE_ERROR;
1634 }
1635
1636 } else if (parser.get_next_token_type() == TK_INDENTIFIER) {
1637 //probably variable
1638
1639 Node *node = p_parent;
1640 bool existing = false;
1641 DataType datatype;
1642 StringName identifier = parser.get_next_token().text;
1643
1644 while (node) {
1645
1646 if (node->type == Node::TYPE_BLOCK) {
1647
1648 BlockNode *block = (BlockNode *)node;
1649
1650 if (block->variables.has(identifier)) {
1651 existing = true;
1652 datatype = block->variables[identifier];
1653 break;
1654 }
1655 }
1656
1657 if (node->type == Node::TYPE_FUNCTION) {
1658
1659 FunctionNode *function = (FunctionNode *)node;
1660 for (int i = 0; i < function->arguments.size(); i++) {
1661 if (function->arguments[i].name == identifier) {
1662 existing = true;
1663 datatype = function->arguments[i].type;
1664 break;
1665 }
1666 }
1667
1668 if (existing)
1669 break;
1670 }
1671
1672 if (node->type == Node::TYPE_PROGRAM) {
1673
1674 ProgramNode *program = (ProgramNode *)node;
1675 if (program->builtin_variables.has(identifier)) {
1676 datatype = program->builtin_variables[identifier];
1677 existing = true;
1678 break;
1679 }
1680 if (program->uniforms.has(identifier)) {
1681 datatype = program->uniforms[identifier].type;
1682 existing = true;
1683 break;
1684 }
1685 }
1686
1687 node = node->parent;
1688 }
1689
1690 if (!existing) {
1691
1692 parser.set_error("Nonexistent identifier in expression: " + identifier);
1693 return ERR_PARSE_ERROR;
1694 }
1695
1696 VariableNode *varname = parser.create_node<VariableNode>(p_parent);
1697 varname->name = identifier;
1698 varname->datatype_cache = datatype;
1699 parser.advance();
1700 expr = varname;
1701
1702 } else if (parser.get_next_token_type() == TK_OP_SUB || parser.get_next_token_type() == TK_OP_NOT) {
1703
1704 //single prefix operators
1705 TokenType token_type = parser.get_next_token_type();
1706 parser.advance();
1707 //Node *subexpr=NULL;
1708 //Error err = parse_expression(parser,p_parent,&subexpr);
1709 //if (err)
1710 // return err;
1711
1712 //OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
1713
1714 Expression e;
1715 e.is_op = true;
1716
1717 switch (token_type) {
1718 case TK_OP_SUB: e.op = TK_OP_NEG; break;
1719 case TK_OP_NOT:
1720 e.op = TK_OP_NOT;
1721 break;
1722 //case TK_OP_PLUS_PLUS: op->op=OP_PLUS_PLUS; break;
1723 //case TK_OP_MINUS_MINUS: op->op=OP_MINUS_MINUS; break;
1724 default: ERR_FAIL_V(ERR_BUG);
1725 }
1726
1727 expression.push_back(e);
1728
1729 continue;
1730
1731 } else {
1732 print_line("found bug?");
1733 print_line("misplaced token: " + String(token_names[parser.get_next_token_type()]));
1734
1735 parser.set_error("Error parsing expression, misplaced: " + String(token_names[parser.get_next_token_type()]));
1736 return ERR_PARSE_ERROR;
1737 //nothing
1738 }
1739
1740 ERR_FAIL_COND_V(!expr, ERR_BUG);
1741
1742 /* OK now see what's NEXT to the operator.. */
1743 /* OK now see what's NEXT to the operator.. */
1744 /* OK now see what's NEXT to the operator.. */
1745
1746 if (parser.get_next_token_type() == TK_PERIOD) {
1747
1748 if (parser.get_next_token_type(1) != TK_INDENTIFIER) {
1749 parser.set_error("Expected identifier as member");
1750 return ERR_PARSE_ERROR;
1751 }
1752
1753 DataType dt = compute_node_type(expr);
1754 String ident = parser.get_next_token(1).text;
1755
1756 bool ok = true;
1757 DataType member_type;
1758 switch (dt) {
1759 case TYPE_VEC2: {
1760
1761 int l = ident.length();
1762 if (l == 1) {
1763 member_type = TYPE_FLOAT;
1764 } else if (l == 2) {
1765 member_type = TYPE_VEC2;
1766 } else {
1767 ok = false;
1768 break;
1769 }
1770
1771 const CharType *c = ident.ptr();
1772 for (int i = 0; i < l; i++) {
1773
1774 switch (c[i]) {
1775 case 'r':
1776 case 'g':
1777 case 'x':
1778 case 'y':
1779 break;
1780 default:
1781 ok = false;
1782 break;
1783 }
1784 }
1785
1786 } break;
1787 case TYPE_VEC3: {
1788
1789 int l = ident.length();
1790 if (l == 1) {
1791 member_type = TYPE_FLOAT;
1792 } else if (l == 2) {
1793 member_type = TYPE_VEC2;
1794 } else if (l == 3) {
1795 member_type = TYPE_VEC3;
1796 } else {
1797 ok = false;
1798 break;
1799 }
1800
1801 const CharType *c = ident.ptr();
1802 for (int i = 0; i < l; i++) {
1803
1804 switch (c[i]) {
1805 case 'r':
1806 case 'g':
1807 case 'b':
1808 case 'x':
1809 case 'y':
1810 case 'z':
1811 break;
1812 default:
1813 ok = false;
1814 break;
1815 }
1816 }
1817
1818 } break;
1819 case TYPE_VEC4: {
1820
1821 int l = ident.length();
1822 if (l == 1) {
1823 member_type = TYPE_FLOAT;
1824 } else if (l == 2) {
1825 member_type = TYPE_VEC2;
1826 } else if (l == 3) {
1827 member_type = TYPE_VEC3;
1828 } else if (l == 4) {
1829 member_type = TYPE_VEC4;
1830 } else {
1831 ok = false;
1832 break;
1833 }
1834
1835 const CharType *c = ident.ptr();
1836 for (int i = 0; i < l; i++) {
1837
1838 switch (c[i]) {
1839 case 'r':
1840 case 'g':
1841 case 'b':
1842 case 'a':
1843 case 'x':
1844 case 'y':
1845 case 'z':
1846 case 'w':
1847 break;
1848 default:
1849 ok = false;
1850 break;
1851 }
1852 }
1853
1854 } break;
1855 case TYPE_MAT2:
1856 ok = (ident == "x" || ident == "y");
1857 member_type = TYPE_VEC2;
1858 break;
1859 case TYPE_MAT3:
1860 ok = (ident == "x" || ident == "y" || ident == "z");
1861 member_type = TYPE_VEC3;
1862 break;
1863 case TYPE_MAT4:
1864 ok = (ident == "x" || ident == "y" || ident == "z" || ident == "w");
1865 member_type = TYPE_VEC4;
1866 break;
1867 default: {}
1868 }
1869
1870 if (!ok) {
1871
1872 parser.set_error("Invalid member for expression: ." + ident);
1873 return ERR_PARSE_ERROR;
1874 }
1875
1876 MemberNode *mn = parser.create_node<MemberNode>(p_parent);
1877 mn->basetype = dt;
1878 mn->datatype = member_type;
1879 mn->name = ident;
1880 mn->owner = expr;
1881 expr = mn;
1882
1883 parser.advance(2);
1884 //todo
1885 //member (period) has priority over any operator
1886 //creates a subindexing expression in place
1887
1888 } else if (parser.get_next_token_type() == TK_BRACKET_OPEN) {
1889 //todo
1890 //subindexing has priority over any operator
1891 //creates a subindexing expression in place
1892
1893 } /*else if (parser.get_next_token_type()==TK_OP_PLUS_PLUS || parser.get_next_token_type()==TK_OP_MINUS_MINUS) {
1894 //todo
1895 //inc/dec operators have priority over any operator
1896 //creates a subindexing expression in place
1897 //return OK; //wtfs
1898
1899 } */
1900
1901 Expression e;
1902 e.is_op = false;
1903 e.node = expr;
1904 expression.push_back(e);
1905
1906 if (is_token_operator(parser.get_next_token_type())) {
1907
1908 Expression o;
1909 o.is_op = true;
1910 o.op = parser.get_next_token_type();
1911 expression.push_back(o);
1912 parser.advance();
1913 } else {
1914 break;
1915 }
1916 }
1917
1918 /* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
1919
1920 while (expression.size() > 1) {
1921
1922 int next_op = -1;
1923 int min_priority = 0xFFFFF;
1924 bool is_unary = false;
1925
1926 for (int i = 0; i < expression.size(); i++) {
1927
1928 if (!expression[i].is_op) {
1929
1930 continue;
1931 }
1932
1933 bool unary = false;
1934
1935 int priority;
1936 switch (expression[i].op) {
1937
1938 case TK_OP_NOT:
1939 priority = 0;
1940 unary = true;
1941 break;
1942 case TK_OP_NEG:
1943 priority = 0;
1944 unary = true;
1945 break;
1946
1947 case TK_OP_MUL: priority = 1; break;
1948 case TK_OP_DIV: priority = 1; break;
1949
1950 case TK_OP_ADD: priority = 2; break;
1951 case TK_OP_SUB:
1952 priority = 2;
1953 break;
1954
1955 // shift left/right =2
1956
1957 case TK_OP_LESS: priority = 4; break;
1958 case TK_OP_LESS_EQUAL: priority = 4; break;
1959 case TK_OP_GREATER: priority = 4; break;
1960 case TK_OP_GREATER_EQUAL: priority = 4; break;
1961
1962 case TK_OP_EQUAL: priority = 5; break;
1963 case TK_OP_NOT_EQUAL:
1964 priority = 5;
1965 break;
1966
1967 //bit and =5
1968 //bit xor =6
1969 //bit or=7
1970
1971 case TK_OP_AND: priority = 8; break;
1972 case TK_OP_OR:
1973 priority = 9;
1974 break;
1975
1976 // ?: = 10
1977
1978 case TK_OP_ASSIGN_ADD: priority = 11; break;
1979 case TK_OP_ASSIGN_SUB: priority = 11; break;
1980 case TK_OP_ASSIGN_MUL: priority = 11; break;
1981 case TK_OP_ASSIGN_DIV: priority = 11; break;
1982 case TK_OP_ASSIGN: priority = 11; break;
1983
1984 default:
1985 ERR_FAIL_V(ERR_BUG); //unexpected operator
1986 }
1987
1988 if (priority < min_priority) {
1989 // < is used for left to right (default)
1990 // <= is used for right to left
1991 next_op = i;
1992 min_priority = priority;
1993 is_unary = unary;
1994 }
1995 }
1996
1997 ERR_FAIL_COND_V(next_op == -1, ERR_BUG);
1998
1999 // OK! create operator..
2000 // OK! create operator..
2001 if (is_unary) {
2002
2003 int expr_pos = next_op;
2004 while (expression[expr_pos].is_op) {
2005
2006 expr_pos++;
2007 if (expr_pos == expression.size()) {
2008 //can happen..
2009 parser.set_error("Unexpected end of expression..");
2010 return ERR_BUG;
2011 }
2012 }
2013
2014 //consecutively do unary opeators
2015 for (int i = expr_pos - 1; i >= next_op; i--) {
2016
2017 OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
2018 op->op = get_token_operator(expression[i].op);
2019 op->arguments.push_back(expression[i + 1].node);
2020
2021 expression[i].is_op = false;
2022 expression[i].node = validate_operator(parser, op);
2023 if (!expression[i].node) {
2024
2025 String at;
2026 for (int i = 0; i < op->arguments.size(); i++) {
2027 if (i > 0)
2028 at += " and ";
2029 at += get_datatype_name(compute_node_type(op->arguments[i]));
2030 }
2031 parser.set_error("Invalid argument to unary operator " + String(token_names[op->op]) + ": " + at);
2032 return ERR_PARSE_ERROR;
2033 }
2034 expression.remove(i + 1);
2035 }
2036 } else {
2037
2038 if (next_op < 1 || next_op >= (expression.size() - 1)) {
2039 parser.set_error("Parser bug..");
2040 ERR_FAIL_V(ERR_BUG);
2041 }
2042
2043 OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
2044 op->op = get_token_operator(expression[next_op].op);
2045
2046 if (expression[next_op - 1].is_op) {
2047
2048 parser.set_error("Parser bug..");
2049 ERR_FAIL_V(ERR_BUG);
2050 }
2051
2052 if (expression[next_op + 1].is_op) {
2053 // this is not invalid and can really appear
2054 // but it becomes invalid anyway because no binary op
2055 // can be followed by an unary op in a valid combination,
2056 // due to how precedence works, unaries will always dissapear first
2057
2058 parser.set_error("Parser bug..");
2059 }
2060
2061 op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
2062 op->arguments.push_back(expression[next_op + 1].node); //next expression goes as right
2063
2064 //replace all 3 nodes by this operator and make it an expression
2065 expression[next_op - 1].node = validate_operator(parser, op);
2066 if (!expression[next_op - 1].node) {
2067
2068 String at;
2069 for (int i = 0; i < op->arguments.size(); i++) {
2070 if (i > 0)
2071 at += " and ";
2072 at += get_datatype_name(compute_node_type(op->arguments[i]));
2073 }
2074 static const char *op_names[OP_MAX] = { "=", "+", "-", "*", "/", "+=", "-=", "*=", "/=", "-", "!", "==", "!=", "<=", ">=", "<", ">", "||", "&&", "call", "()" };
2075
2076 parser.set_error("Invalid arguments to operator " + String(op_names[op->op]) + ": " + at);
2077 return ERR_PARSE_ERROR;
2078 }
2079 expression.remove(next_op);
2080 expression.remove(next_op);
2081 }
2082
2083 #if 0
2084 OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
2085 op->op=get_token_operator(operators[next_op]);
2086
2087 op->arguments.push_back(expressions[next_op]); //expression goes as left
2088 op->arguments.push_back(expressions[next_op+1]); //next expression goes as right
2089
2090 expressions[next_op]=validate_operator(parser,op);
2091 if (!expressions[next_op]) {
2092
2093 String at;
2094 for(int i=0;i<op->arguments.size();i++) {
2095 if (i>0)
2096 at+=" and ";
2097 at+=get_datatype_name(compute_node_type(op->arguments[i]));
2098
2099 }
2100 parser.set_error("Invalid arguments to operator "+String(token_names[operators[next_op]])+": "+at);
2101 return ERR_PARSE_ERROR;
2102 }
2103
2104
2105 expressions.remove(next_op+1);
2106 operators.remove(next_op);
2107 #endif
2108 }
2109
2110 *r_expr = expression[0].node;
2111
2112 return OK;
2113
2114 /*
2115 TokenType token_type=parser.get_next_token_type();
2116 OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
2117 op->op=get_token_operator(parser.get_next_token_type());
2118
2119 op->arguments.push_back(*r_expr); //expression goes as left
2120 parser.advance();
2121 Node *right_expr=NULL;
2122 Error err = parse_expression(parser,p_parent,&right_expr);
2123 if (err)
2124 return err;
2125 op->arguments.push_back(right_expr);
2126
2127 if (!validate_operator(op)) {
2128
2129 parser.set_error("Invalid arguments to operator "+String(token_names[token_type]));
2130 return ERR_PARSE_ERROR;
2131 }
2132
2133 */
2134 }
2135
parse_variable_declaration(Parser & parser,BlockNode * p_block)2136 Error ShaderLanguage::parse_variable_declaration(Parser &parser, BlockNode *p_block) {
2137
2138 bool uniform = parser.get_next_token(-1).type == TK_UNIFORM;
2139
2140 DataType type = get_token_datatype(parser.get_next_token_type(0));
2141 bool iscolor = parser.get_next_token_type(0) == TK_TYPE_COLOR;
2142
2143 if (type == TYPE_VOID) {
2144
2145 parser.set_error("Cannot Declare a 'void' Variable");
2146 return ERR_PARSE_ERROR;
2147 }
2148
2149 if (type == TYPE_TEXTURE && !uniform) {
2150
2151 parser.set_error("Cannot Declare a Non-Uniform Texture");
2152 return ERR_PARSE_ERROR;
2153 }
2154 if (type == TYPE_CUBEMAP && !uniform) {
2155
2156 parser.set_error("Cannot Declare a Non-Uniform Cubemap");
2157 return ERR_PARSE_ERROR;
2158 }
2159
2160 parser.advance();
2161 int found = 0;
2162
2163 while (true) {
2164
2165 if (found && parser.get_next_token_type() != TK_COMMA) {
2166 break;
2167 }
2168
2169 if (parser.get_next_token_type() != TK_INDENTIFIER) {
2170
2171 parser.set_error("Identifier Expected");
2172 return ERR_PARSE_ERROR;
2173 }
2174
2175 StringName name = parser.get_next_token().text;
2176
2177 if (test_existing_identifier(p_block, name)) {
2178 parser.set_error("Duplicate Identifier (existing variable/function): " + name);
2179 return ERR_PARSE_ERROR;
2180 }
2181
2182 found = true;
2183
2184 parser.advance();
2185 //see if declaration has an initializer
2186 if (parser.get_next_token_type() == TK_OP_ASSIGN) {
2187 parser.advance();
2188 OperatorNode *op = parser.create_node<OperatorNode>(p_block);
2189 VariableNode *var = parser.create_node<VariableNode>(op);
2190 var->name = name;
2191 var->datatype_cache = type;
2192 var->uniform = uniform;
2193 Node *expr;
2194 Error err = parse_expression(parser, p_block, &expr);
2195
2196 if (err)
2197 return err;
2198
2199 if (var->uniform) {
2200
2201 if (expr->type != Node::TYPE_CONSTANT) {
2202
2203 parser.set_error("Uniform can only be initialized to a constant.");
2204 return ERR_PARSE_ERROR;
2205 }
2206
2207 Uniform u;
2208 u.order = parser.program->uniforms.size();
2209 u.type = type;
2210 u.default_value = static_cast<ConstantNode *>(expr)->value;
2211 if (iscolor && u.default_value.get_type() == Variant::PLANE) {
2212 Color c;
2213 Plane p = u.default_value;
2214 c = Color(p.normal.x, p.normal.y, p.normal.z, p.d);
2215 u.default_value = c;
2216 }
2217 parser.program->uniforms[var->name] = u;
2218 } else {
2219 op->op = OP_ASSIGN;
2220 op->arguments.push_back(var);
2221 op->arguments.push_back(expr);
2222 Node *n = validate_operator(parser, op);
2223 if (!n) {
2224 parser.set_error("Invalid initializer for variable: " + name);
2225 return ERR_PARSE_ERROR;
2226 }
2227 p_block->statements.push_back(n);
2228 }
2229
2230 } else {
2231 //initialize it EMPTY
2232
2233 OperatorNode *op = parser.create_node<OperatorNode>(p_block);
2234 VariableNode *var = parser.create_node<VariableNode>(op);
2235 ConstantNode *con = parser.create_node<ConstantNode>(op);
2236
2237 var->name = name;
2238 var->datatype_cache = type;
2239 var->uniform = uniform;
2240 con->datatype = type;
2241
2242 switch (type) {
2243 case TYPE_BOOL: con->value = false; break;
2244 case TYPE_FLOAT: con->value = 0.0; break;
2245 case TYPE_VEC2: con->value = Vector2(); break;
2246 case TYPE_VEC3: con->value = Vector3(); break;
2247 case TYPE_VEC4: con->value = iscolor ? Variant(Color()) : Variant(Plane()); break;
2248 case TYPE_MAT2: con->value = Matrix32(); break;
2249 case TYPE_MAT3: con->value = Matrix3(); break;
2250 case TYPE_MAT4: con->value = Transform(); break;
2251 case TYPE_TEXTURE:
2252 case TYPE_CUBEMAP: con->value = RID(); break;
2253 default: {}
2254 }
2255
2256 if (uniform) {
2257 Uniform u;
2258 u.type = type;
2259 u.default_value = con->value;
2260 u.order = parser.program->uniforms.size();
2261 parser.program->uniforms[var->name] = u;
2262
2263 } else {
2264 op->op = OP_ASSIGN;
2265 op->arguments.push_back(var);
2266 op->arguments.push_back(con);
2267 p_block->statements.push_back(op);
2268 }
2269 }
2270
2271 if (!uniform)
2272 p_block->variables[name] = type;
2273 }
2274
2275 if (parser.get_next_token_type() != TK_SEMICOLON) {
2276 parser.set_error("Expected ';'");
2277 return ERR_PARSE_ERROR;
2278 }
2279
2280 return OK;
2281 }
2282
parse_flow_if(Parser & parser,Node * p_parent,Node ** r_statement)2283 Error ShaderLanguage::parse_flow_if(Parser &parser, Node *p_parent, Node **r_statement) {
2284
2285 ControlFlowNode *cf = parser.create_node<ControlFlowNode>(p_parent);
2286
2287 cf->flow_op = FLOW_OP_IF;
2288
2289 parser.advance();
2290
2291 if (parser.get_next_token_type() != TK_PARENTHESIS_OPEN) {
2292 parser.set_error("Expected '(' after 'if'");
2293 return ERR_PARSE_ERROR;
2294 }
2295 parser.advance();
2296
2297 Node *expression = NULL;
2298 Error err = parse_expression(parser, cf, &expression);
2299 if (err)
2300 return err;
2301
2302 if (compute_node_type(expression) != TYPE_BOOL) {
2303
2304 parser.set_error("Expression for 'if' is not boolean");
2305 return ERR_PARSE_ERROR;
2306 }
2307
2308 cf->statements.push_back(expression);
2309
2310 if (parser.get_next_token_type() != TK_PARENTHESIS_CLOSE) {
2311 parser.set_error("Expected ')' after expression");
2312 return ERR_PARSE_ERROR;
2313 }
2314
2315 parser.advance();
2316
2317 if (parser.get_next_token_type() != TK_CURLY_BRACKET_OPEN) {
2318 parser.set_error("Expected statement block after 'if()'");
2319 return ERR_PARSE_ERROR;
2320 }
2321
2322 Node *substatement = NULL;
2323 err = parse_statement(parser, cf, &substatement);
2324 if (err)
2325 return err;
2326
2327 cf->statements.push_back(substatement);
2328
2329 if (parser.get_next_token_type() == TK_CF_ELSE) {
2330
2331 parser.advance();
2332
2333 if (parser.get_next_token_type() != TK_CURLY_BRACKET_OPEN) {
2334 parser.set_error("Expected statement block after 'else'");
2335 return ERR_PARSE_ERROR;
2336 }
2337
2338 substatement = NULL;
2339 err = parse_statement(parser, cf, &substatement);
2340 if (err)
2341 return err;
2342
2343 cf->statements.push_back(substatement);
2344 }
2345
2346 *r_statement = cf;
2347
2348 return OK;
2349 }
2350
parse_flow_return(Parser & parser,Node * p_parent,Node ** r_statement)2351 Error ShaderLanguage::parse_flow_return(Parser &parser, Node *p_parent, Node **r_statement) {
2352
2353 FunctionNode *function = NULL;
2354
2355 Node *parent = p_parent;
2356
2357 while (parent) {
2358
2359 if (parent->type == Node::TYPE_FUNCTION) {
2360
2361 function = (FunctionNode *)parent;
2362 break;
2363 }
2364
2365 parent = parent->parent;
2366 }
2367
2368 if (!function) {
2369
2370 parser.set_error("'return' must be inside a function");
2371 return ERR_PARSE_ERROR;
2372 }
2373
2374 ControlFlowNode *cf = parser.create_node<ControlFlowNode>(p_parent);
2375
2376 cf->flow_op = FLOW_OP_RETURN;
2377
2378 parser.advance();
2379
2380 if (function->return_type != TYPE_VOID) {
2381 // should expect a return expression.
2382
2383 Node *expr = NULL;
2384 Error err = parse_expression(parser, cf, &expr);
2385 if (err)
2386 return err;
2387
2388 if (compute_node_type(expr) != function->return_type) {
2389 parser.set_error("Invalid type for 'return' expression");
2390 return ERR_PARSE_ERROR;
2391 }
2392 cf->statements.push_back(expr);
2393 }
2394
2395 *r_statement = cf;
2396
2397 if (parser.get_next_token_type() != TK_SEMICOLON) {
2398 parser.set_error("Expected ';'");
2399 return ERR_PARSE_ERROR;
2400 }
2401
2402 return OK;
2403 }
2404
parse_statement(Parser & parser,Node * p_parent,Node ** r_statement)2405 Error ShaderLanguage::parse_statement(Parser &parser, Node *p_parent, Node **r_statement) {
2406
2407 *r_statement = NULL;
2408
2409 TokenType token_type = parser.get_next_token_type();
2410
2411 if (token_type == TK_CURLY_BRACKET_OPEN) {
2412 //sub-block
2413 parser.advance();
2414 BlockNode *block = parser.create_node<BlockNode>(p_parent);
2415
2416 *r_statement = block;
2417 return parse_block(parser, block);
2418 } else if (token_type == TK_SEMICOLON) {
2419 // empty ;
2420 parser.advance();
2421 return OK;
2422 } else if (token_type == TK_CF_IF) {
2423 return parse_flow_if(parser, p_parent, r_statement);
2424
2425 } else if (token_type == TK_CF_RETURN) {
2426 return parse_flow_return(parser, p_parent, r_statement);
2427 } else {
2428 Error err = parse_expression(parser, p_parent, r_statement);
2429
2430 if (err)
2431 return err;
2432
2433 if (parser.get_next_token_type() != TK_SEMICOLON) {
2434 parser.set_error("Expected ';'");
2435 return ERR_PARSE_ERROR;
2436 }
2437 }
2438
2439 return OK;
2440 }
2441
parse_block(Parser & parser,BlockNode * p_block)2442 Error ShaderLanguage::parse_block(Parser &parser, BlockNode *p_block) {
2443
2444 while (true) {
2445
2446 if (parser.is_at_end()) {
2447 if (p_block->parent->type != Node::TYPE_PROGRAM) {
2448 parser.set_error("Unexpected End of File");
2449 return ERR_PARSE_ERROR;
2450 }
2451 return OK; //bye
2452 }
2453
2454 TokenType token_type = parser.get_next_token_type();
2455
2456 if (token_type == TK_CURLY_BRACKET_CLOSE) {
2457 if (p_block->parent->type == Node::TYPE_PROGRAM) {
2458 parser.set_error("Unexpected '}'");
2459 return ERR_PARSE_ERROR;
2460 }
2461 parser.advance();
2462 return OK; // exit block
2463
2464 } else if (token_type == TK_UNIFORM) {
2465
2466 if (p_block != parser.program->body) {
2467
2468 parser.set_error("Uniform only allowed in main program body.");
2469 return ERR_PARSE_ERROR;
2470 }
2471 parser.advance();
2472 Error err = parse_variable_declaration(parser, p_block);
2473 if (err)
2474 return err;
2475
2476 } else if (is_token_datatype(token_type)) {
2477
2478 Error err = OK;
2479 if (parser_is_at_function(parser))
2480 err = parse_function(parser, p_block);
2481 else {
2482 err = parse_variable_declaration(parser, p_block);
2483 }
2484
2485 if (err)
2486 return err;
2487
2488 } else {
2489 // must be a statement
2490 Node *statement = NULL;
2491
2492 Error err = parse_statement(parser, p_block, &statement);
2493 if (err)
2494 return err;
2495 if (statement) {
2496 p_block->statements.push_back(statement);
2497 }
2498 }
2499 }
2500
2501 return OK;
2502 }
2503
parse(const Vector<Token> & p_tokens,ShaderType p_type,CompileFunc p_compile_func,void * p_userdata,String * r_error,int * r_err_line,int * r_err_column)2504 Error ShaderLanguage::parse(const Vector<Token> &p_tokens, ShaderType p_type, CompileFunc p_compile_func, void *p_userdata, String *r_error, int *r_err_line, int *r_err_column) {
2505
2506 Parser parser(p_tokens);
2507 parser.program = parser.create_node<ProgramNode>(NULL);
2508 parser.program->body = parser.create_node<BlockNode>(parser.program);
2509
2510 //add builtins
2511 switch (p_type) {
2512 case SHADER_MATERIAL_VERTEX: {
2513 int idx = 0;
2514 while (vertex_builtins_defs[idx].name) {
2515 parser.program->builtin_variables[vertex_builtins_defs[idx].name] = vertex_builtins_defs[idx].type;
2516 idx++;
2517 }
2518 } break;
2519 case SHADER_MATERIAL_FRAGMENT: {
2520 int idx = 0;
2521 while (fragment_builtins_defs[idx].name) {
2522 parser.program->builtin_variables[fragment_builtins_defs[idx].name] = fragment_builtins_defs[idx].type;
2523 idx++;
2524 }
2525 } break;
2526 case SHADER_MATERIAL_LIGHT: {
2527 int idx = 0;
2528 while (light_builtins_defs[idx].name) {
2529 parser.program->builtin_variables[light_builtins_defs[idx].name] = light_builtins_defs[idx].type;
2530 idx++;
2531 }
2532 } break;
2533 case SHADER_CANVAS_ITEM_VERTEX: {
2534 int idx = 0;
2535 while (ci_vertex_builtins_defs[idx].name) {
2536 parser.program->builtin_variables[ci_vertex_builtins_defs[idx].name] = ci_vertex_builtins_defs[idx].type;
2537 idx++;
2538 }
2539 } break;
2540 case SHADER_CANVAS_ITEM_FRAGMENT: {
2541 int idx = 0;
2542 while (ci_fragment_builtins_defs[idx].name) {
2543 parser.program->builtin_variables[ci_fragment_builtins_defs[idx].name] = ci_fragment_builtins_defs[idx].type;
2544 idx++;
2545 }
2546 } break;
2547 case SHADER_CANVAS_ITEM_LIGHT: {
2548 int idx = 0;
2549 while (ci_light_builtins_defs[idx].name) {
2550 parser.program->builtin_variables[ci_light_builtins_defs[idx].name] = ci_light_builtins_defs[idx].type;
2551 idx++;
2552 }
2553 } break;
2554 case SHADER_POST_PROCESS: {
2555 int idx = 0;
2556 while (postprocess_fragment_builtins_defs[idx].name) {
2557 parser.program->builtin_variables[postprocess_fragment_builtins_defs[idx].name] = postprocess_fragment_builtins_defs[idx].type;
2558 idx++;
2559 }
2560 } break;
2561 }
2562
2563 Error err = parse_block(parser, parser.program->body);
2564 if (err) {
2565 parser.get_error(r_error, r_err_line, r_err_column);
2566 return err;
2567 }
2568
2569 if (p_compile_func) {
2570 err = p_compile_func(p_userdata, parser.program);
2571 }
2572
2573 //clean up nodes created
2574 while (parser.nodegc.size()) {
2575
2576 memdelete(parser.nodegc.front()->get());
2577 parser.nodegc.pop_front();
2578 }
2579 return err;
2580 }
2581
compile(const String & p_code,ShaderType p_type,CompileFunc p_compile_func,void * p_userdata,String * r_error,int * r_err_line,int * r_err_column)2582 Error ShaderLanguage::compile(const String &p_code, ShaderType p_type, CompileFunc p_compile_func, void *p_userdata, String *r_error, int *r_err_line, int *r_err_column) {
2583
2584 *r_error = "";
2585 *r_err_line = 0;
2586 *r_err_column = 0;
2587 Vector<Token> tokens;
2588
2589 Error err = tokenize(p_code, &tokens, r_error, r_err_line, r_err_column);
2590 if (err != OK) {
2591 print_line("tokenizer error!");
2592 }
2593
2594 if (err != OK) {
2595 return err;
2596 }
2597 err = parse(tokens, p_type, p_compile_func, p_userdata, r_error, r_err_line, r_err_column);
2598 if (err != OK) {
2599 return err;
2600 }
2601 return OK;
2602 }
2603
get_keyword_list(ShaderType p_type,List<String> * p_keywords)2604 void ShaderLanguage::get_keyword_list(ShaderType p_type, List<String> *p_keywords) {
2605
2606 int idx = 0;
2607
2608 p_keywords->push_back("uniform");
2609 p_keywords->push_back("texture");
2610 p_keywords->push_back("cubemap");
2611 p_keywords->push_back("color");
2612 p_keywords->push_back("if");
2613 p_keywords->push_back("else");
2614
2615 while (intrinsic_func_defs[idx].name) {
2616
2617 p_keywords->push_back(intrinsic_func_defs[idx].name);
2618 idx++;
2619 }
2620
2621 switch (p_type) {
2622 case SHADER_MATERIAL_VERTEX: {
2623 idx = 0;
2624 while (vertex_builtins_defs[idx].name) {
2625 p_keywords->push_back(vertex_builtins_defs[idx].name);
2626 idx++;
2627 }
2628 } break;
2629 case SHADER_MATERIAL_FRAGMENT: {
2630 idx = 0;
2631 while (fragment_builtins_defs[idx].name) {
2632 p_keywords->push_back(fragment_builtins_defs[idx].name);
2633 idx++;
2634 }
2635 } break;
2636 case SHADER_MATERIAL_LIGHT: {
2637 idx = 0;
2638 while (light_builtins_defs[idx].name) {
2639 p_keywords->push_back(light_builtins_defs[idx].name);
2640 idx++;
2641 }
2642 } break;
2643 case SHADER_CANVAS_ITEM_VERTEX: {
2644 idx = 0;
2645 while (ci_vertex_builtins_defs[idx].name) {
2646 p_keywords->push_back(ci_vertex_builtins_defs[idx].name);
2647 idx++;
2648 }
2649 } break;
2650 case SHADER_CANVAS_ITEM_FRAGMENT: {
2651 idx = 0;
2652 while (ci_fragment_builtins_defs[idx].name) {
2653 p_keywords->push_back(ci_fragment_builtins_defs[idx].name);
2654 idx++;
2655 }
2656 } break;
2657 case SHADER_CANVAS_ITEM_LIGHT: {
2658 idx = 0;
2659 while (ci_light_builtins_defs[idx].name) {
2660 p_keywords->push_back(ci_light_builtins_defs[idx].name);
2661 idx++;
2662 }
2663 } break;
2664
2665 case SHADER_POST_PROCESS: {
2666 idx = 0;
2667 while (postprocess_fragment_builtins_defs[idx].name) {
2668 p_keywords->push_back(postprocess_fragment_builtins_defs[idx].name);
2669 idx++;
2670 }
2671 } break;
2672 }
2673 }
2674