📄 slang_compile.c
字号:
slang_struct *s; O->structs->structs = (slang_struct *) _slang_realloc(O->structs->structs, O->structs->num_structs * sizeof(slang_struct), (O->structs->num_structs + 1) * sizeof(slang_struct)); if (O->structs->structs == NULL) { slang_info_log_memory(C->L); return 0; } s = &O->structs->structs[O->structs->num_structs]; if (!slang_struct_construct(s)) return 0; O->structs->num_structs++; if (!slang_struct_copy(s, *st)) return 0; } return 1;}/* type qualifier */#define TYPE_QUALIFIER_NONE 0#define TYPE_QUALIFIER_CONST 1#define TYPE_QUALIFIER_ATTRIBUTE 2#define TYPE_QUALIFIER_VARYING 3#define TYPE_QUALIFIER_UNIFORM 4#define TYPE_QUALIFIER_FIXEDOUTPUT 5#define TYPE_QUALIFIER_FIXEDINPUT 6static intparse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual){ switch (*C->I++) { case TYPE_QUALIFIER_NONE: *qual = SLANG_QUAL_NONE; break; case TYPE_QUALIFIER_CONST: *qual = SLANG_QUAL_CONST; break; case TYPE_QUALIFIER_ATTRIBUTE: *qual = SLANG_QUAL_ATTRIBUTE; break; case TYPE_QUALIFIER_VARYING: *qual = SLANG_QUAL_VARYING; break; case TYPE_QUALIFIER_UNIFORM: *qual = SLANG_QUAL_UNIFORM; break; case TYPE_QUALIFIER_FIXEDOUTPUT: *qual = SLANG_QUAL_FIXEDOUTPUT; break; case TYPE_QUALIFIER_FIXEDINPUT: *qual = SLANG_QUAL_FIXEDINPUT; break; default: return 0; } return 1;}/* type specifier */#define TYPE_SPECIFIER_VOID 0#define TYPE_SPECIFIER_BOOL 1#define TYPE_SPECIFIER_BVEC2 2#define TYPE_SPECIFIER_BVEC3 3#define TYPE_SPECIFIER_BVEC4 4#define TYPE_SPECIFIER_INT 5#define TYPE_SPECIFIER_IVEC2 6#define TYPE_SPECIFIER_IVEC3 7#define TYPE_SPECIFIER_IVEC4 8#define TYPE_SPECIFIER_FLOAT 9#define TYPE_SPECIFIER_VEC2 10#define TYPE_SPECIFIER_VEC3 11#define TYPE_SPECIFIER_VEC4 12#define TYPE_SPECIFIER_MAT2 13#define TYPE_SPECIFIER_MAT3 14#define TYPE_SPECIFIER_MAT4 15#define TYPE_SPECIFIER_SAMPLER1D 16#define TYPE_SPECIFIER_SAMPLER2D 17#define TYPE_SPECIFIER_SAMPLER3D 18#define TYPE_SPECIFIER_SAMPLERCUBE 19#define TYPE_SPECIFIER_SAMPLER1DSHADOW 20#define TYPE_SPECIFIER_SAMPLER2DSHADOW 21#define TYPE_SPECIFIER_SAMPLER2DRECT 22#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23#define TYPE_SPECIFIER_STRUCT 24#define TYPE_SPECIFIER_TYPENAME 25#define TYPE_SPECIFIER_MAT23 26#define TYPE_SPECIFIER_MAT32 27#define TYPE_SPECIFIER_MAT24 28#define TYPE_SPECIFIER_MAT42 29#define TYPE_SPECIFIER_MAT34 30#define TYPE_SPECIFIER_MAT43 31#define TYPE_SPECIFIER_COUNT 32static intparse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, slang_type_specifier * spec){ switch (*C->I++) { case TYPE_SPECIFIER_VOID: spec->type = SLANG_SPEC_VOID; break; case TYPE_SPECIFIER_BOOL: spec->type = SLANG_SPEC_BOOL; break; case TYPE_SPECIFIER_BVEC2: spec->type = SLANG_SPEC_BVEC2; break; case TYPE_SPECIFIER_BVEC3: spec->type = SLANG_SPEC_BVEC3; break; case TYPE_SPECIFIER_BVEC4: spec->type = SLANG_SPEC_BVEC4; break; case TYPE_SPECIFIER_INT: spec->type = SLANG_SPEC_INT; break; case TYPE_SPECIFIER_IVEC2: spec->type = SLANG_SPEC_IVEC2; break; case TYPE_SPECIFIER_IVEC3: spec->type = SLANG_SPEC_IVEC3; break; case TYPE_SPECIFIER_IVEC4: spec->type = SLANG_SPEC_IVEC4; break; case TYPE_SPECIFIER_FLOAT: spec->type = SLANG_SPEC_FLOAT; break; case TYPE_SPECIFIER_VEC2: spec->type = SLANG_SPEC_VEC2; break; case TYPE_SPECIFIER_VEC3: spec->type = SLANG_SPEC_VEC3; break; case TYPE_SPECIFIER_VEC4: spec->type = SLANG_SPEC_VEC4; break; case TYPE_SPECIFIER_MAT2: spec->type = SLANG_SPEC_MAT2; break; case TYPE_SPECIFIER_MAT3: spec->type = SLANG_SPEC_MAT3; break; case TYPE_SPECIFIER_MAT4: spec->type = SLANG_SPEC_MAT4; break; case TYPE_SPECIFIER_MAT23: spec->type = SLANG_SPEC_MAT23; break; case TYPE_SPECIFIER_MAT32: spec->type = SLANG_SPEC_MAT32; break; case TYPE_SPECIFIER_MAT24: spec->type = SLANG_SPEC_MAT24; break; case TYPE_SPECIFIER_MAT42: spec->type = SLANG_SPEC_MAT42; break; case TYPE_SPECIFIER_MAT34: spec->type = SLANG_SPEC_MAT34; break; case TYPE_SPECIFIER_MAT43: spec->type = SLANG_SPEC_MAT43; break; case TYPE_SPECIFIER_SAMPLER1D: spec->type = SLANG_SPEC_SAMPLER1D; break; case TYPE_SPECIFIER_SAMPLER2D: spec->type = SLANG_SPEC_SAMPLER2D; break; case TYPE_SPECIFIER_SAMPLER3D: spec->type = SLANG_SPEC_SAMPLER3D; break; case TYPE_SPECIFIER_SAMPLERCUBE: spec->type = SLANG_SPEC_SAMPLERCUBE; break; case TYPE_SPECIFIER_SAMPLER2DRECT: spec->type = SLANG_SPEC_SAMPLER2DRECT; break; case TYPE_SPECIFIER_SAMPLER1DSHADOW: spec->type = SLANG_SPEC_SAMPLER1DSHADOW; break; case TYPE_SPECIFIER_SAMPLER2DSHADOW: spec->type = SLANG_SPEC_SAMPLER2DSHADOW; break; case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW: spec->type = SLANG_SPEC_SAMPLER2DRECTSHADOW; break; case TYPE_SPECIFIER_STRUCT: spec->type = SLANG_SPEC_STRUCT; if (!parse_struct(C, O, &spec->_struct)) return 0; break; case TYPE_SPECIFIER_TYPENAME: spec->type = SLANG_SPEC_STRUCT; { slang_atom a_name; slang_struct *stru; a_name = parse_identifier(C); if (a_name == NULL) return 0; stru = slang_struct_scope_find(O->structs, a_name, 1); if (stru == NULL) { slang_info_log_error(C->L, "undeclared type name '%s'", slang_atom_pool_id(C->atoms, a_name)); return 0; } spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct)); if (spec->_struct == NULL) { slang_info_log_memory(C->L); return 0; } if (!slang_struct_construct(spec->_struct)) { _slang_free(spec->_struct); spec->_struct = NULL; return 0; } if (!slang_struct_copy(spec->_struct, stru)) return 0; } break; default: return 0; } return 1;}#define PRECISION_DEFAULT 0#define PRECISION_LOW 1#define PRECISION_MEDIUM 2#define PRECISION_HIGH 3static intparse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, slang_fully_specified_type * type){ GLuint precision; if (!parse_type_qualifier(C, &type->qualifier)) return 0; precision = *C->I++; if (!parse_type_specifier(C, O, &type->specifier)) return 0; switch (precision) { case PRECISION_DEFAULT: assert(type->specifier.type < TYPE_SPECIFIER_COUNT); if (type->specifier.type < TYPE_SPECIFIER_COUNT) type->precision = O->default_precision[type->specifier.type]; break; case PRECISION_LOW: type->precision = SLANG_PREC_LOW; break; case PRECISION_MEDIUM: type->precision = SLANG_PREC_MEDIUM; break; case PRECISION_HIGH: type->precision = SLANG_PREC_HIGH; break; default: return 0; }#if !FEATURE_es2_glsl if (precision != PRECISION_DEFAULT) { slang_info_log_error(C->L, "precision qualifiers not allowed"); return 0; }#endif return 1;}/* operation */#define OP_END 0#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1#define OP_BLOCK_BEGIN_NEW_SCOPE 2#define OP_DECLARE 3#define OP_ASM 4#define OP_BREAK 5#define OP_CONTINUE 6#define OP_DISCARD 7#define OP_RETURN 8#define OP_EXPRESSION 9#define OP_IF 10#define OP_WHILE 11#define OP_DO 12#define OP_FOR 13#define OP_PUSH_VOID 14#define OP_PUSH_BOOL 15#define OP_PUSH_INT 16#define OP_PUSH_FLOAT 17#define OP_PUSH_IDENTIFIER 18#define OP_SEQUENCE 19#define OP_ASSIGN 20#define OP_ADDASSIGN 21#define OP_SUBASSIGN 22#define OP_MULASSIGN 23#define OP_DIVASSIGN 24/*#define OP_MODASSIGN 25*//*#define OP_LSHASSIGN 26*//*#define OP_RSHASSIGN 27*//*#define OP_ORASSIGN 28*//*#define OP_XORASSIGN 29*//*#define OP_ANDASSIGN 30*/#define OP_SELECT 31#define OP_LOGICALOR 32#define OP_LOGICALXOR 33#define OP_LOGICALAND 34/*#define OP_BITOR 35*//*#define OP_BITXOR 36*//*#define OP_BITAND 37*/#define OP_EQUAL 38#define OP_NOTEQUAL 39#define OP_LESS 40#define OP_GREATER 41#define OP_LESSEQUAL 42#define OP_GREATEREQUAL 43/*#define OP_LSHIFT 44*//*#define OP_RSHIFT 45*/#define OP_ADD 46#define OP_SUBTRACT 47#define OP_MULTIPLY 48#define OP_DIVIDE 49/*#define OP_MODULUS 50*/#define OP_PREINCREMENT 51#define OP_PREDECREMENT 52#define OP_PLUS 53#define OP_MINUS 54/*#define OP_COMPLEMENT 55*/#define OP_NOT 56#define OP_SUBSCRIPT 57#define OP_CALL 58#define OP_FIELD 59#define OP_POSTINCREMENT 60#define OP_POSTDECREMENT 61/** * When parsing a compound production, this function is used to parse the * children. * For example, a while-loop compound will have two children, the * while condition expression and the loop body. So, this function will * be called twice to parse those two sub-expressions. * \param C the parsing context * \param O the output context * \param oper the operation we're parsing * \param statement indicates whether parsing a statement, or expression * \return 1 if success, 0 if error */static intparse_child_operation(slang_parse_ctx * C, slang_output_ctx * O, slang_operation * oper, GLboolean statement){ slang_operation *ch; /* grow child array */ ch = slang_operation_grow(&oper->num_children, &oper->children); if (statement) return parse_statement(C, O, ch); return parse_expression(C, O, ch);}static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);static intparse_statement(slang_parse_ctx * C, slang_output_ctx * O, slang_operation * oper){ oper->locals->outer_scope = O->vars; switch (*C->I++) { case OP_BLOCK_BEGIN_NO_NEW_SCOPE: /* parse child statements, do not create new variable scope */ oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; while (*C->I != OP_END) if (!parse_child_operation(C, O, oper, 1)) return 0; C->I++; break; case OP_BLOCK_BEGIN_NEW_SCOPE: /* parse child statements, create new variable scope */ { slang_output_ctx o = *O; oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; o.vars = oper->locals; while (*C->I != OP_END) if (!parse_child_operation(C, &o, oper, 1)) return 0; C->I++; } break; case OP_DECLARE: /* local variable declaration, individual declarators are stored as * children identifiers */ oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; { const unsigned int first_var = O->vars->num_variables; /* parse the declaration, note that there can be zero or more * than one declarators */ if (!parse_declaration(C, O)) return 0; if (first_var < O->vars->num_variables) { const unsigned int num_vars = O->vars->num_variables - first_var; unsigned int i; assert(oper->num_children == 0); oper->num_children = num_vars; oper->children = slang_operation_new(num_vars); if (oper->children == NULL) { slang_info_log_memory(C->L); return 0; } for (i = first_var; i < O->vars->num_variables; i++) { slang_operation *o = &oper->children[i - first_var]; o->type = SLANG_OPER_VARIABLE_DECL; o->locals->outer_scope = O->vars; o->a_id = O->vars->variables[i]->a_name; if (!legal_identifier(o->a_id)) { slang_info_log_error(C->L, "illegal variable name '%s'", (char *) o->a_id); return 0; } } } } break; case OP_ASM: /* the __asm statement, parse the mnemonic and all its arguments * as expressions */ oper->type = SLANG_OPER_ASM; oper->a_id = parse_identifier(C); if (oper->a_id == SLANG_ATOM_NULL) return 0; while (*C->I != OP_END) { if (!parse_child_operation(C, O, oper, 0)) return 0; } C->I++; break; case OP_BREAK: oper->type = SLANG_OPER_BREAK; break; case OP_CONTINUE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -