📄 slang_compile.c
字号:
return 0;
}
if (!slang_struct_construct_a (spec->_struct))
{
slang_alloc_free (spec->_struct);
spec->_struct = NULL;
slang_alloc_free (name);
slang_info_log_memory (C->L);
return 0;
}
spec->_struct->name = name;
spec->_struct->structs->outer_scope = structs;
}
do
{
slang_type_specifier sp;
slang_type_specifier_construct (&sp);
if (!parse_type_specifier (C, &sp, spec->_struct->structs, scope, funcs))
{
slang_type_specifier_destruct (&sp);
return 0;
}
do
{
slang_variable *var;
spec->_struct->fields->variables = (slang_variable *) slang_alloc_realloc (
spec->_struct->fields->variables,
spec->_struct->fields->num_variables * sizeof (slang_variable),
(spec->_struct->fields->num_variables + 1) * sizeof (slang_variable));
if (spec->_struct->fields->variables == NULL)
{
slang_type_specifier_destruct (&sp);
slang_info_log_memory (C->L);
return 0;
}
var = spec->_struct->fields->variables + spec->_struct->fields->num_variables;
spec->_struct->fields->num_variables++;
slang_variable_construct (var);
if (!slang_type_specifier_copy (&var->type.specifier, &sp))
{
slang_type_specifier_destruct (&sp);
return 0;
}
if (!parse_identifier (C, &var->name))
{
slang_type_specifier_destruct (&sp);
return 0;
}
switch (*C->I++)
{
case FIELD_NONE:
break;
case FIELD_ARRAY:
var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (
slang_operation));
if (var->array_size == NULL)
{
slang_type_specifier_destruct (&sp);
slang_info_log_memory (C->L);
return 0;
}
if (!slang_operation_construct_a (var->array_size))
{
slang_alloc_free (var->array_size);
var->array_size = NULL;
slang_type_specifier_destruct (&sp);
slang_info_log_memory (C->L);
return 0;
}
if (!parse_expression (C, var->array_size, scope, structs, funcs))
{
slang_type_specifier_destruct (&sp);
return 0;
}
break;
default:
return 0;
}
}
while (*C->I++ != FIELD_NONE);
}
while (*C->I++ != FIELD_NONE);
if (*spec->_struct->name != '\0')
{
slang_struct *s;
structs->structs = (slang_struct *) slang_alloc_realloc (structs->structs,
structs->num_structs * sizeof (slang_struct),
(structs->num_structs + 1) * sizeof (slang_struct));
if (structs->structs == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
s = structs->structs + structs->num_structs;
if (!slang_struct_construct_a (s))
return 0;
structs->num_structs++;
if (!slang_struct_copy (s, spec->_struct))
return 0;
}
break;
case TYPE_SPECIFIER_TYPENAME:
spec->type = slang_spec_struct;
{
char *name;
slang_struct *stru;
if (!parse_identifier (C, &name))
return 0;
stru = slang_struct_scope_find (structs, name, 1);
if (stru == NULL)
{
slang_info_log_error (C->L, "%s: undeclared type name", name);
slang_alloc_free (name);
return 0;
}
slang_alloc_free (name);
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_a (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_fully_specified_type *type,
slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
if (!parse_type_qualifier (C, &type->qualifier))
return 0;
return parse_type_specifier (C, &type->specifier, structs, scope, funcs);
}
/* 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
static int parse_child_operation (slang_parse_ctx *C, slang_operation *oper, int statement,
slang_variable_scope *scope, slang_struct_scope *structs, slang_function_scope *funcs)
{
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;
}
if (!slang_operation_construct_a (oper->children + oper->num_children))
{
slang_info_log_memory (C->L);
return 0;
}
oper->num_children++;
if (statement)
return parse_statement (C, oper->children + oper->num_children - 1, scope, structs, funcs);
return parse_expression (C, oper->children + oper->num_children - 1, scope, structs, funcs);
}
static int parse_declaration (slang_parse_ctx *C, slang_variable_scope *, slang_struct_scope *,
slang_function_scope *);
static int parse_statement (slang_parse_ctx *C, slang_operation *oper, slang_variable_scope *scope,
slang_struct_scope *structs, slang_function_scope *funcs)
{
oper->locals->outer_scope = scope;
switch (*C->I++)
{
case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
oper->type = slang_oper_block_no_new_scope;
while (*C->I != OP_END)
if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
return 0;
C->I++;
break;
case OP_BLOCK_BEGIN_NEW_SCOPE:
oper->type = slang_oper_block_new_scope;
while (*C->I != OP_END)
if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
return 0;
C->I++;
break;
case OP_DECLARE:
oper->type = slang_oper_variable_decl;
{
const unsigned int first_var = scope->num_variables;
if (!parse_declaration (C, scope, structs, funcs))
return 0;
if (first_var < scope->num_variables)
{
const unsigned int num_vars = scope->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 (i = 0; i < num_vars; i++)
if (!slang_operation_construct_a (oper->children + i))
{
unsigned int j;
for (j = 0; j < i; j++)
slang_operation_destruct (oper->children + j);
slang_alloc_free (oper->children);
oper->children = NULL;
slang_info_log_memory (C->L);
return 0;
}
oper->num_children = num_vars;
for (i = first_var; i < scope->num_variables; i++)
{
slang_operation *o = oper->children + i - first_var;
o->type = slang_oper_identifier;
o->locals->outer_scope = scope;
o->identifier = slang_string_duplicate (scope->variables[i].name);
if (o->identifier == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
}
}
}
break;
case OP_ASM:
oper->type = slang_oper_asm;
if (!parse_identifier (C, &oper->identifier))
return 0;
while (*C->I != OP_END)
if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
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, oper, 0, scope, structs, funcs))
return 0;
break;
case OP_EXPRESSION:
oper->type = slang_oper_expression;
if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
return 0;
break;
case OP_IF:
oper->type = slang_oper_if;
if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
return 0;
if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
return 0;
if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
return 0;
break;
case OP_WHILE:
oper->type = slang_oper_while;
if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
return 0;
if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
return 0;
break;
case OP_DO:
oper->type = slang_oper_do;
if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
return 0;
if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
return 0;
break;
case OP_FOR:
oper->type = slang_oper_for;
if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
return 0;
if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
return 0;
if (!parse_child_operation (C, oper, 0, oper->locals, structs, funcs))
return 0;
if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
return 0;
break;
default:
return 0;
}
return 1;
}
static int handle_trinary_expression (slang_parse_ctx *C, slang_operation *op,
slang_operation **ops, unsigned int *num_ops)
{
op->num_children = 3;
op->children = (slang_operation *) slang_alloc_malloc (3 * sizeof (slang_operation));
if (op->children == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
op->children[0] = (*ops)[*num_ops - 4];
op->children[1] = (*ops)[*num_ops - 3];
op->children[2] = (*ops)[*num_ops - 2];
(*ops)[*num_ops - 4] = (*ops)[*num_ops - 1];
*num_ops -= 3;
*ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 3) * sizeof (slang_operation),
*num_ops * sizeof (slang_operation));
if (*ops == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
return 1;
}
static int handle_binary_expression (slang_parse_ctx *C, slang_operation *op,
slang_operation **ops, unsigned int *num_ops)
{
op->num_children = 2;
op->children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
if (op->children == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
op->children[0] = (*ops)[*num_ops - 3];
op->children[1] = (*ops)[*num_ops - 2];
(*ops)[*num_ops - 3] = (*ops)[*num_ops - 1];
*num_ops -= 2;
*ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 2) * sizeof (slang_operation),
*num_ops * sizeof (slang_operation));
if (*ops == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
return 1;
}
static int handle_unary_expression (slang_parse_ctx *C, slang_operation *op,
slang_operation **ops, unsigned int *num_ops)
{
op->num_children = 1;
op->children = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
if (op->children == NULL)
{
slang_info_log_memory (C->L);
return 0;
}
op->children[0] = (*ops)[*num_ops - 2];
(*ops)[*num_ops - 2] = (*ops)[*num_ops - 1];
(*num_ops)--;
*ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 1) * sizeof (slang_operation),
*num_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_struct_scope *structs)
{
if (slang_type_specifier_type_from_string (name) != slang_spec_void)
return 1;
return slang_struct_scope_find (structs, name, 1) != NULL;
}
static int parse_expression (slang_parse_ctx *C, slang_operation *oper, slang_variable_scope *scope,
slang_struct_scope *structs, slang_function_scope *funcs)
{
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++;
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_a (op))
{
slang_info_log_memory (C->L);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -