📄 slang_compile.c
字号:
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 inthandle_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_new(n); if (op->children == NULL) { slang_info_log_memory(C->L); return 0; } op->num_children = n; for (i = 0; i < n; i++) { slang_operation_destruct(&op->children[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_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 intis_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 intparse_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_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[0] = op->literal[1] = op->literal[2] = op->literal[3] = (GLfloat) number; op->literal_size = 1; break; case OP_PUSH_INT: op->type = SLANG_OPER_LITERAL_INT; if (!parse_number(C, &number)) return 0; op->literal[0] = op->literal[1] = op->literal[2] = op->literal[3] = (GLfloat) number; op->literal_size = 1; break; case OP_PUSH_FLOAT: op->type = SLANG_OPER_LITERAL_FLOAT; if (!parse_float(C, &op->literal[0])) return 0; op->literal[1] = op->literal[2] = op->literal[3] = op->literal[0]; op->literal_size = 1; 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)) return 0; break; case OP_SUBASSIGN: op->type = SLANG_OPER_SUBASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_MULASSIGN: op->type = SLANG_OPER_MULASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_DIVASSIGN: op->type = SLANG_OPER_DIVASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_MODASSIGN: */ /*case OP_LSHASSIGN: */ /*case OP_RSHASSIGN: */ /*case OP_ORASSIGN: */ /*case OP_XORASSIGN: */ /*case OP_ANDASSIGN: */ case OP_SELECT: op->type = SLANG_OPER_SELECT; if (!handle_nary_expression(C, op, &ops, &num_ops, 3)) return 0; break; case OP_LOGICALOR: op->type = SLANG_OPER_LOGICALOR; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LOGICALXOR: op->type = SLANG_OPER_LOGICALXOR; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LOGICALAND: op->type = SLANG_OPER_LOGICALAND; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_BITOR: */ /*case OP_BITXOR: */ /*case OP_BITAND: */ case OP_EQUAL: op->type = SLANG_OPER_EQUAL; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_NOTEQUAL: op->type = SLANG_OPER_NOTEQUAL; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LESS: op->type = SLANG_OPER_LESS; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_GREATER: op->type = SLANG_OPER_GREATER; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LESSEQUAL: op->type = SLANG_OPER_LESSEQUAL; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_GREATEREQUAL: op->type = SLANG_OPER_GREATEREQUAL; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_LSHIFT: */ /*case OP_RSHIFT: */ case OP_ADD: op->type = SLANG_OPER_ADD; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_SUBTRACT: op->type = SLANG_OPER_SUBTRACT; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_MULTIPLY: op->type = SLANG_OPER_MULTIPLY; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_DIVIDE: op->type = SLANG_OPER_DIVIDE; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_MODULUS: */ case OP_PREINCREMENT: op->type = SLANG_OPER_PREINCREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_PREDECREMENT: op->type = SLANG_OPER_PREDECREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_PLUS: op->type = SLANG_OPER_PLUS; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_MINUS: op->type = SLANG_OPER_MINUS; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_NOT: op->type = SLANG_OPER_NOT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; /*case OP_COMPLEMENT: */ case OP_SUBSCRIPT: op->type = SLANG_OPER_SUBSCRIPT; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_CALL: op->type = SLANG_OPER_CALL; op->a_id = parse_identifier(C); if (op->a_id == SLANG_ATOM_NULL) return 0; while (*C->I != OP_END) if (!parse_child_operation(C, O, op, 0)) return 0; C->I++; if (!C->parsing_builtin && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) { const char *id; id = slang_atom_pool_id(C->atoms, op->a_id); if (!is_constructor_name(id, op->a_id, O->structs)) { slang_info_log_error(C->L, "%s: undeclared function name.", id); return 0; } } break; case OP_FIELD: op->type = SLANG_OPER_FIELD; op->a_id = parse_identifier(C); if (op->a_id == SLANG_ATOM_NULL) return 0; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_POSTINCREMENT: op->type = SLANG_OPER_POSTINCREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_POSTDECREMENT: op->type = SLANG_OPER_POSTDECREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; default: return 0; } } C->I++; slang_operation_destruct(oper); *oper = *ops; /* struct copy */ _slang_free(ops); return 1;}/* parameter qualifier */#define PARAM_QUALIFIER_IN 0#define PARAM_QUALIFIER_OUT 1#define PARAM_QUALIFIER_INOUT 2/* function parameter array presence */#define PARAMETER_ARRAY_NOT_PRESENT 0#define PARAMETER_ARRAY_PRESENT 1static intparse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O, slang_variable * param){ /* parse and validate the parameter's type qualifiers (there can be * two at most) because not all combinations are valid */ if (!parse_type_qualifier(C, ¶m->type.qualifier)) return 0; switch (*C->I++) { case PARAM_QUALIFIER_IN: if (param->type.qualifier != SLANG_QUAL_CONST && param->type.qualifier != SLANG_QUAL_NONE) { slang_info_log_error(C->L, "Invalid type qualifier."); return 0; } break; case PARAM_QUALIFIER_OUT: if (param->type.qualifier == SLANG_QUAL_NONE) param->type.qualifier = SLANG_QUAL_OUT; else { slang_info_log_error(C->L, "Invalid type qualifier."); return 0; } break; case PARAM_QUALIFIER_INOUT: if (param->type.qualifier == SLANG_QUAL_NONE) param->type.qualifier = SLANG_QUAL_INOUT; else { slang_info_log_error(C->L, "Invalid type qualifier."); return 0; } break; default: return 0; } /* parse parameter's type specifier and name */ if (!parse_type_specifier(C, O, ¶m->type.specifier)) return 0; param->a_name = parse_identifier(C); if (param->a_name == SLANG_ATOM_NULL) return 0; /* if the parameter is an array, parse its size (the size must be * explicitly defined */ if (*C->I++ == PARAMETER_ARRAY_PRESENT) { slang_type_specifier p; slang_type_specifier_ctr(&p); if (!slang_type_specifier_copy(&p, ¶m->type.specifier)) { slang_type_specifier_dtr(&p); return GL_FALSE; } if (!convert_to_array(C, param, &p)) { slang_type_specifier_dtr(&p); return GL_FALSE; } slang_type_specifier_dtr(&p); if (!parse_array_len(C, O, ¶m->array_len)) return GL_FALSE; } /* calculate the parameter size */ if (!calculate_var_size(C, O, param)) return GL_FALSE; /* TODO: allocate the local address here? */ return 1;}/* function type */#define FUNCTION_ORDINARY 0#define FUNCTION_CONSTRUCTOR 1#define FUNCTION_OPERATOR 2/* function parameter */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -