📄 slang_compile.c
字号:
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 int parse_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_STRUCT 22#define TYPE_SPECIFIER_TYPENAME 23static int parse_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_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_SAMPLER1DSHADOW: spec->type = slang_spec_sampler1DShadow; break; case TYPE_SPECIFIER_SAMPLER2DSHADOW: spec->type = slang_spec_sampler2DShadow; 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, "%s: undeclared type name", slang_atom_pool_id (C->atoms, a_name)); return 0; } spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); if (spec->_struct == NULL) { slang_info_log_memory (C->L); return 0; } if (!slang_struct_construct (spec->_struct)) { slang_alloc_free (spec->_struct); spec->_struct = NULL; return 0; } if (!slang_struct_copy (spec->_struct, stru)) return 0; } break; default: return 0; } return 1;}static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O, slang_fully_specified_type *type){ if (!parse_type_qualifier (C, &type->qualifier)) return 0; return parse_type_specifier (C, O, &type->specifier);}/* 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 61static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper, int statement){ slang_operation *ch; oper->children = (slang_operation *) slang_alloc_realloc (oper->children, oper->num_children * sizeof (slang_operation), (oper->num_children + 1) * sizeof (slang_operation)); if (oper->children == NULL) { slang_info_log_memory (C->L); return 0; } ch = &oper->children[oper->num_children]; if (!slang_operation_construct (ch)) { slang_info_log_memory (C->L); return 0; } oper->num_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 int parse_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_variable_decl; { 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; oper->children = (slang_operation *) slang_alloc_malloc (num_vars * sizeof ( slang_operation)); if (oper->children == NULL) { slang_info_log_memory (C->L); return 0; } for (oper->num_children = 0; oper->num_children < num_vars; oper->num_children++) if (!slang_operation_construct (&oper->children[oper->num_children])) { 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_identifier; o->locals->outer_scope = O->vars; o->a_id = O->vars->variables[i].a_name; } } } 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: oper->type = slang_oper_continue; break; case OP_DISCARD: oper->type = slang_oper_discard; break; case OP_RETURN: oper->type = slang_oper_return; if (!parse_child_operation (C, O, oper, 0)) return 0; break; case OP_EXPRESSION: oper->type = slang_oper_expression; if (!parse_child_operation (C, O, oper, 0)) return 0; break; case OP_IF: oper->type = slang_oper_if; if (!parse_child_operation (C, O, oper, 0)) return 0; if (!parse_child_operation (C, O, oper, 1)) return 0; if (!parse_child_operation (C, O, oper, 1)) return 0; break; case OP_WHILE: { slang_output_ctx o = *O; oper->type = slang_oper_while; o.vars = oper->locals; if (!parse_child_operation (C, &o, oper, 1)) return 0; if (!parse_child_operation (C, &o, oper, 1)) return 0; } break; case OP_DO: oper->type = slang_oper_do; if (!parse_child_operation (C, O, oper, 1)) return 0; if (!parse_child_operation (C, O, oper, 0)) return 0; break; case OP_FOR: { slang_output_ctx o = *O; oper->type = slang_oper_for; o.vars = oper->locals; if (!parse_child_operation (C, &o, oper, 1)) return 0; if (!parse_child_operation (C, &o, oper, 1)) return 0; if (!parse_child_operation (C, &o, oper, 0)) return 0; if (!parse_child_operation (C, &o, oper, 1)) return 0; } break; default: return 0; } return 1;}static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops, unsigned int *total_ops, unsigned int n){ unsigned int i; op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation)); if (op->children == NULL) { slang_info_log_memory (C->L); return 0; } op->num_children = n; for (i = 0; i < n; i++) op->children[i] = (*ops)[*total_ops - (n + 1 - i)]; (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1]; *total_ops -= n; *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation), *total_ops * sizeof (slang_operation)); if (*ops == NULL) { slang_info_log_memory (C->L); return 0; } return 1;}static int is_constructor_name (const char *name, slang_atom a_name, slang_struct_scope *structs){ if (slang_type_specifier_type_from_string (name) != slang_spec_void) return 1; return slang_struct_scope_find (structs, a_name, 1) != NULL;}static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper){ slang_operation *ops = NULL; unsigned int num_ops = 0; int number; while (*C->I != OP_END) { slang_operation *op; const unsigned int op_code = *C->I++; /* allocate default operation, becomes a no-op if not used */ ops = (slang_operation *) slang_alloc_realloc (ops, num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation)); if (ops == NULL) { slang_info_log_memory (C->L); return 0; } op = &ops[num_ops]; if (!slang_operation_construct (op)) { slang_info_log_memory (C->L); return 0; } num_ops++; op->locals->outer_scope = O->vars; switch (op_code) { case OP_PUSH_VOID: op->type = slang_oper_void; break; case OP_PUSH_BOOL: op->type = slang_oper_literal_bool; if (!parse_number (C, &number)) return 0; op->literal = (GLfloat) number; break; case OP_PUSH_INT: op->type = slang_oper_literal_int; if (!parse_number (C, &number)) return 0; op->literal = (GLfloat) number; break; case OP_PUSH_FLOAT: op->type = slang_oper_literal_float; if (!parse_float (C, &op->literal)) return 0; break; case OP_PUSH_IDENTIFIER: op->type = slang_oper_identifier; op->a_id = parse_identifier (C); if (op->a_id == SLANG_ATOM_NULL) return 0; break; case OP_SEQUENCE: op->type = slang_oper_sequence; if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_ASSIGN: op->type = slang_oper_assign; if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_ADDASSIGN: op->type = slang_oper_addassign; if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -