📄 slang_compile.c
字号:
num_ops++;
op->locals->outer_scope = scope;
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 = (float) number;
break;
case OP_PUSH_INT:
op->type = slang_oper_literal_int;
if (!parse_number (C, &number))
return 0;
op->literal = (float) 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;
if (!parse_identifier (C, &op->identifier))
return 0;
break;
case OP_SEQUENCE:
op->type = slang_oper_sequence;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_ASSIGN:
op->type = slang_oper_assign;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_ADDASSIGN:
op->type = slang_oper_addassign;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_SUBASSIGN:
op->type = slang_oper_subassign;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_MULASSIGN:
op->type = slang_oper_mulassign;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_DIVASSIGN:
op->type = slang_oper_divassign;
if (!handle_binary_expression (C, op, &ops, &num_ops))
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_trinary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_LOGICALOR:
op->type = slang_oper_logicalor;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_LOGICALXOR:
op->type = slang_oper_logicalxor;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_LOGICALAND:
op->type = slang_oper_logicaland;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
/*case OP_BITOR:*/
/*case OP_BITXOR:*/
/*case OP_BITAND:*/
case OP_EQUAL:
op->type = slang_oper_equal;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_NOTEQUAL:
op->type = slang_oper_notequal;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_LESS:
op->type = slang_oper_less;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_GREATER:
op->type = slang_oper_greater;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_LESSEQUAL:
op->type = slang_oper_lessequal;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_GREATEREQUAL:
op->type = slang_oper_greaterequal;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
/*case OP_LSHIFT:*/
/*case OP_RSHIFT:*/
case OP_ADD:
op->type = slang_oper_add;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_SUBTRACT:
op->type = slang_oper_subtract;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_MULTIPLY:
op->type = slang_oper_multiply;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_DIVIDE:
op->type = slang_oper_divide;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
/*case OP_MODULUS:*/
case OP_PREINCREMENT:
op->type = slang_oper_preincrement;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_PREDECREMENT:
op->type = slang_oper_predecrement;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_PLUS:
op->type = slang_oper_plus;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_MINUS:
op->type = slang_oper_minus;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_NOT:
op->type = slang_oper_not;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
/*case OP_COMPLEMENT:*/
case OP_SUBSCRIPT:
op->type = slang_oper_subscript;
if (!handle_binary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_CALL:
op->type = slang_oper_call;
if (!parse_identifier (C, &op->identifier))
return 0;
while (*C->I != OP_END)
if (!parse_child_operation (C, op, 0, scope, structs, funcs))
return 0;
C->I++;
if (!C->parsing_builtin &&
!slang_function_scope_find_by_name (funcs, op->identifier, 1) &&
!is_constructor_name (op->identifier, structs))
{
slang_info_log_error (C->L, "%s: undeclared function name", op->identifier);
return 0;
}
break;
case OP_FIELD:
op->type = slang_oper_field;
if (!parse_identifier (C, &op->identifier))
return 0;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_POSTINCREMENT:
op->type = slang_oper_postincrement;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
case OP_POSTDECREMENT:
op->type = slang_oper_postdecrement;
if (!handle_unary_expression (C, op, &ops, &num_ops))
return 0;
break;
default:
return 0;
}
}
C->I++;
*oper = *ops;
slang_alloc_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 1
static int parse_parameter_declaration (slang_parse_ctx *C, slang_variable *param,
slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
slang_storage_aggregate agg;
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;
}
if (!parse_type_specifier (C, ¶m->type.specifier, structs, scope, funcs))
return 0;
if (!parse_identifier (C, ¶m->name))
return 0;
if (*C->I++ == PARAMETER_ARRAY_PRESENT)
{
param->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
if (param->array_size == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
if (!slang_operation_construct_a (param->array_size))
{
slang_alloc_free (param->array_size);
param->array_size = NULL;
slang_info_log_memory (C->L);
return 0;
}
if (!parse_expression (C, param->array_size, scope, structs, funcs))
return 0;
}
slang_storage_aggregate_construct (&agg);
if (!_slang_aggregate_variable (&agg, ¶m->type.specifier, param->array_size, funcs,
structs))
{
slang_storage_aggregate_destruct (&agg);
return 0;
}
slang_storage_aggregate_destruct (&agg);
return 1;
}
/* function type */
#define FUNCTION_ORDINARY 0
#define FUNCTION_CONSTRUCTOR 1
#define FUNCTION_OPERATOR 2
/* function parameter */
#define PARAMETER_NONE 0
#define PARAMETER_NEXT 1
/* operator type */
#define OPERATOR_ASSIGN 1
#define OPERATOR_ADDASSIGN 2
#define OPERATOR_SUBASSIGN 3
#define OPERATOR_MULASSIGN 4
#define OPERATOR_DIVASSIGN 5
/*#define OPERATOR_MODASSIGN 6*/
/*#define OPERATOR_LSHASSIGN 7*/
/*#define OPERATOR_RSHASSIGN 8*/
/*#define OPERATOR_ANDASSIGN 9*/
/*#define OPERATOR_XORASSIGN 10*/
/*#define OPERATOR_ORASSIGN 11*/
#define OPERATOR_LOGICALXOR 12
/*#define OPERATOR_BITOR 13*/
/*#define OPERATOR_BITXOR 14*/
/*#define OPERATOR_BITAND 15*/
#define OPERATOR_EQUAL 16
#define OPERATOR_NOTEQUAL 17
#define OPERATOR_LESS 18
#define OPERATOR_GREATER 19
#define OPERATOR_LESSEQUAL 20
#define OPERATOR_GREATEREQUAL 21
/*#define OPERATOR_LSHIFT 22*/
/*#define OPERATOR_RSHIFT 23*/
#define OPERATOR_MULTIPLY 24
#define OPERATOR_DIVIDE 25
/*#define OPERATOR_MODULUS 26*/
#define OPERATOR_INCREMENT 27
#define OPERATOR_DECREMENT 28
#define OPERATOR_PLUS 29
#define OPERATOR_MINUS 30
/*#define OPERATOR_COMPLEMENT 31*/
#define OPERATOR_NOT 32
static const struct {
unsigned int o_code;
const char *o_name;
} operator_names[] = {
{ OPERATOR_INCREMENT, "++" },
{ OPERATOR_ADDASSIGN, "+=" },
{ OPERATOR_PLUS, "+" },
{ OPERATOR_DECREMENT, "--" },
{ OPERATOR_SUBASSIGN, "-=" },
{ OPERATOR_MINUS, "-" },
{ OPERATOR_NOTEQUAL, "!=" },
{ OPERATOR_NOT, "!" },
{ OPERATOR_MULASSIGN, "*=" },
{ OPERATOR_MULTIPLY, "*" },
{ OPERATOR_DIVASSIGN, "/=" },
{ OPERATOR_DIVIDE, "/" },
{ OPERATOR_LESSEQUAL, "<=" },
/*{ OPERATOR_LSHASSIGN, "<<=" },*/
/*{ OPERATOR_LSHIFT, "<<" },*/
{ OPERATOR_LESS, "<" },
{ OPERATOR_GREATEREQUAL, ">=" },
/*{ OPERATOR_RSHASSIGN, ">>=" },*/
/*{ OPERATOR_RSHIFT, ">>" },*/
{ OPERATOR_GREATER, ">" },
{ OPERATOR_EQUAL, "==" },
{ OPERATOR_ASSIGN, "=" },
/*{ OPERATOR_MODASSIGN, "%=" },*/
/*{ OPERATOR_MODULUS, "%" },*/
/*{ OPERATOR_ANDASSIGN, "&=" },*/
/*{ OPERATOR_BITAND, "&" },*/
/*{ OPERATOR_ORASSIGN, "|=" },*/
/*{ OPERATOR_BITOR, "|" },*/
/*{ OPERATOR_COMPLEMENT, "~" },*/
/*{ OPERATOR_XORASSIGN, "^=" },*/
{ OPERATOR_LOGICALXOR, "^^" }/*,*/
/*{ OPERATOR_BITXOR, "^" }*/
};
static int parse_operator_name (slang_parse_ctx *C, char **pname)
{
unsigned int i;
for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)
if (operator_names[i].o_code == (unsigned int) (*C->I))
{
*pname = slang_string_duplicate (operator_names[i].o_name);
if (*pname == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
C->I++;
return 1;
}
return 0;
}
static int parse_function_prototype (slang_parse_ctx *C, slang_function *func,
slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
if (!parse_fully_specified_type (C, &func->header.type, structs, scope, funcs))
return 0;
switch (*C->I++)
{
case FUNCTION_ORDINARY:
func->kind = slang_func_ordinary;
if (!parse_identifier (C, &func->header.name))
return 0;
break;
case FUNCTION_CONSTRUCTOR:
func->kind = slang_func_constructor;
if (func->header.type.specifier.type == slang_spec_struct)
return 0;
func->header.name = slang_string_duplicate (
type_specifier_type_names[func->header.type.specifier.type]);
if (func->header.name == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
break;
case FUNCTION_OPERATOR:
func->kind = slang_func_operator;
if (!parse_operator_name (C, &func->header.name))
return 0;
break;
default:
return 0;
}
func->parameters->outer_scope = scope;
while (*C->I++ == PARAMETER_NEXT)
{
func->parameters->variables = (slang_variable *) slang_alloc_realloc (
func->parameters->variables,
func->parameters->num_variables * sizeof (slang_variable),
(func->parameters->num_variables + 1) * sizeof (slang_variable));
if (func->parameters->variables == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
slang_variable_construct (func->parameters->variables + func->parameters->num_variables);
func->parameters->num_variables++;
if (!parse_parameter_declaration (C, func->parameters->variables +
func->parameters->num_variables - 1, structs, scope, funcs))
return 0;
}
func->param_count = func->parameters->num_variables;
return 1;
}
static int parse_function_definition (slang_parse_ctx *C, slang_function *func,
slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
if (!parse_function_prototype (C, func, structs, scope, funcs))
return 0;
func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
if (func->body == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
if (!slang_operation_construct_a (func->body))
{
slang_alloc_free (func->body);
func->body = NULL;
slang_info_log_memory (C->L);
return 0;
}
if (!parse_statement (C, func->body, func->parameters, structs, funcs))
return 0;
return 1;
}
/* init declarator list */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -