代码拉取完成,页面将自动刷新
/* // 运行 */
#include <math.h>
#include <string.h>
#include <setjmp.h>
#include "MEM.h"
#include "DBG.h"
#include "wuji.h"
static StatementResult
execute_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement);
static StatementResult
execute_expression_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
result.type = NORMAL_STATEMENT_RESULT;
wj_eval_expression(inter, env, statement->u.expression_s);
return result;
}
static StatementResult
execute_global_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
IdentifierList *pos;
StatementResult result;
result.type = NORMAL_STATEMENT_RESULT;
if (env == NULL) {
wj_runtime_error(statement->line_number,
GLOBAL_STATEMENT_IN_TOPLEVEL_ERR,
MESSAGE_ARGUMENT_END);
}
for (pos = statement->u.global_s.identifier_list; pos; pos = pos->next) {
GlobalVariableRef *ref_pos;
GlobalVariableRef *new_ref;
Variable *variable;
for (ref_pos = env->global_variable; ref_pos;
ref_pos = ref_pos->next) {
if (!strcmp(ref_pos->name, pos->name))
goto NEXT_IDENTIFIER;
}
variable = wj_search_global_variable(inter, pos->name);
if (variable == NULL) {
wj_runtime_error(statement->line_number,
GLOBAL_VARIABLE_NOT_FOUND_ERR,
STRING_MESSAGE_ARGUMENT, "name", pos->name,
MESSAGE_ARGUMENT_END);
}
new_ref = MEM_malloc(sizeof(GlobalVariableRef));
new_ref->name = pos->name;
new_ref->variable = variable;
new_ref->next = env->global_variable;
env->global_variable = new_ref;
NEXT_IDENTIFIER:
;
}
return result;
}
static StatementResult
execute_elsif(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Elsif *elsif_list, WJ_Boolean *executed)
{
StatementResult result;
WJ_Value cond;
Elsif *pos;
*executed = WJ_FALSE;
result.type = NORMAL_STATEMENT_RESULT;
for (pos = elsif_list; pos; pos = pos->next) {
cond = wj_eval_expression(inter, env, pos->condition);
if (cond.type != WJ_BOOLEAN_VALUE) {
wj_runtime_error(pos->condition->line_number,
NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
}
if (cond.u.boolean_value) {
result = wj_execute_statement_list(inter, env,
pos->block->statement_list);
*executed = WJ_TRUE;
if (result.type != NORMAL_STATEMENT_RESULT)
goto FUNC_END;
}
}
FUNC_END:
return result;
}
static StatementResult
execute_if_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
WJ_Value cond;
result.type = NORMAL_STATEMENT_RESULT;
cond = wj_eval_expression(inter, env, statement->u.if_s.condition);
if (cond.type != WJ_BOOLEAN_VALUE) {
wj_runtime_error(statement->u.if_s.condition->line_number,
NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
}
DBG_assert(cond.type == WJ_BOOLEAN_VALUE, ("cond.type..%d", cond.type));
if (cond.u.boolean_value) {
result = wj_execute_statement_list(inter, env,
statement->u.if_s.then_block
->statement_list);
} else {
WJ_Boolean elsif_executed;
result = execute_elsif(inter, env, statement->u.if_s.elsif_list,
&elsif_executed);
if (result.type != NORMAL_STATEMENT_RESULT)
goto FUNC_END;
if (!elsif_executed && statement->u.if_s.else_block) {
result = wj_execute_statement_list(inter, env,
statement->u.if_s.else_block
->statement_list);
}
}
FUNC_END:
return result;
}
static StatementResultType
compare_labels(char *result_label, char *loop_laber,
StatementResultType current_result)
{
if (result_label == NULL) {
return NORMAL_STATEMENT_RESULT;
}
if (loop_laber && !strcmp(result_label, loop_laber)) {
return NORMAL_STATEMENT_RESULT;
} else {
return current_result;
}
}
static StatementResult
execute_while_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
WJ_Value cond;
result.type = NORMAL_STATEMENT_RESULT;
for (;;) {
cond = wj_eval_expression(inter, env, statement->u.while_s.condition);
if (cond.type != WJ_BOOLEAN_VALUE) {
wj_runtime_error(statement->u.while_s.condition->line_number,
NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
}
DBG_assert(cond.type == WJ_BOOLEAN_VALUE,
("cond.type..%d", cond.type));
if (!cond.u.boolean_value)
break;
result = wj_execute_statement_list(inter, env,
statement->u.while_s.block
->statement_list);
if (result.type == RETURN_STATEMENT_RESULT) {
break;
} else if (result.type == BREAK_STATEMENT_RESULT) {
result.type = NORMAL_STATEMENT_RESULT;
break;
} else if (result.type == CONTINUE_STATEMENT_RESULT) {
result.type = NORMAL_STATEMENT_RESULT;
break;
}
}
return result;
}
static StatementResult
execute_for_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
WJ_Value cond;
result.type = NORMAL_STATEMENT_RESULT;
if (statement->u.for_s.init) {
wj_eval_expression(inter, env, statement->u.for_s.init);
}
for (;;) {
if (statement->u.for_s.condition) {
cond = wj_eval_expression(inter, env,
statement->u.for_s.condition);
if (cond.type != WJ_BOOLEAN_VALUE) {
wj_runtime_error(statement->u.for_s.condition->line_number,
NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
}
DBG_assert(cond.type == WJ_BOOLEAN_VALUE,
("cond.type..%d", cond.type));
if (!cond.u.boolean_value)
break;
}
result = wj_execute_statement_list(inter, env,
statement->u.for_s.block
->statement_list);
if (result.type == RETURN_STATEMENT_RESULT) {
break;
} else if (result.type == BREAK_STATEMENT_RESULT) {
result.type = compare_labels(result.u.label,
statement->u.for_s.label, result.type);
break;
} else if (result.type == CONTINUE_STATEMENT_RESULT) {
result.type = compare_labels(result.u.label,
statement->u.for_s.label, result.type);
}
if (statement->u.for_s.post) {
wj_eval_expression(inter, env, statement->u.for_s.post);
}
}
return result;
}
static WJ_Value *
assign_to_variable(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
int line_number, char *name, WJ_Value *value)
{
WJ_Value *ret;
ret = wj_get_identifier_lvalue(inter, env, line_number, name);
if (!ret) {
if (env) {
ret = WJ_add_local_variable(inter, env, name, value, WJ_FALSE);
} else {
/* if (wj_search_function(inter, name)) { */
if (wj_search_function(name)) {
wj_runtime_error(line_number, FUNCTION_EXISTS_ERR,
STRING_MESSAGE_ARGUMENT, "name", name,
MESSAGE_ARGUMENT_END);
}
ret = WJ_add_global_variable(inter, name, value, WJ_FALSE);
}
} else {
*ret = *value;
}
return ret;
}
static StatementResult
execute_foreach_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
WJ_Value *collection;
WJ_Value iterator;
WJ_Value *var;
WJ_Value is_done;
int stack_count = 0;
WJ_Value temp;
result.type = NORMAL_STATEMENT_RESULT;
collection = wj_eval_and_peek_expression(inter, env,
statement->u.foreach_s.collection);
stack_count++;
collection = WJ_peek_stack(inter, 0);
iterator = WJ_call_method(inter, env, statement->line_number,
collection->u.object, ARRAY_METHOD_ITERATOR,
0, NULL);
WJ_push_value(inter, &iterator);
stack_count++;
temp.type = WJ_NULL_VALUE;
var = assign_to_variable(inter, env, statement->line_number,
statement->u.foreach_s.variable, &temp);
for (;;) {
is_done = WJ_call_method(inter, env, statement->line_number,
iterator.u.object, IS_DONE_METHOD_NAME,
0, NULL);
if (is_done.type != WJ_BOOLEAN_VALUE) {
wj_runtime_error(statement->line_number, NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END);
}
if (is_done.u.boolean_value)
break;
*var = WJ_call_method(inter, env, statement->line_number,
iterator.u.object, CURRENT_ITEM_METHOD_NAME,
0, NULL);
result = wj_execute_statement_list(inter, env, statement->u.for_s.block->statement_list);
if (result.type == RETURN_STATEMENT_RESULT) {
break;
} else if (result.type == BREAK_STATEMENT_RESULT) {
result.type = compare_labels(result.u.label, statement->u.for_s.label, result.type);
break;
} else if (result.type == CONTINUE_STATEMENT_RESULT) {
result.type = compare_labels(result.u.label, statement->u.for_s.label, result.type);
}
WJ_call_method(inter, env, statement->line_number, iterator.u.object,
NEXT_METHOD_NAME, 0, NULL);
}
WJ_shrink_stack(inter, stack_count);
return result;
}
static StatementResult
execute_return_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
result.type = RETURN_STATEMENT_RESULT;
if (statement->u.return_s.return_value) {
result.u.return_value
= wj_eval_expression(inter, env,
statement->u.return_s.return_value);
} else {
result.u.return_value.type = WJ_NULL_VALUE;
}
return result;
}
static StatementResult
execute_break_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
result.type = BREAK_STATEMENT_RESULT;
return result;
}
static StatementResult
execute_continue_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
result.type = CONTINUE_STATEMENT_RESULT;
return result;
}
static StatementResult
execute_throw_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
WJ_Value *ex_val;
ex_val = wj_eval_and_peek_expression(inter, env,
statement->u.throw_s.exception);
inter->current_exception = *ex_val;
WJ_shrink_stack(inter, 1);
longjmp(inter->current_recovery_environment.environment, LONGJMP_ARG);
}
static StatementResult
execute_statement(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
Statement *statement)
{
StatementResult result;
result.type = NORMAL_STATEMENT_RESULT;
switch (statement->type) {
case EXPRESSION_STATEMENT:
result = execute_expression_statement(inter, env, statement);
break;
case GLOBAL_STATEMENT:
result = execute_global_statement(inter, env, statement);
break;
case IF_STATEMENT:
result = execute_if_statement(inter, env, statement);
break;
case WHILE_STATEMENT:
result = execute_while_statement(inter, env, statement);
break;
case FOR_STATEMENT:
result = execute_for_statement(inter, env, statement);
break;
case FOREACH_STATEMENT:
result = execute_foreach_statement(inter, env, statement);
break;
case RETURN_STATEMENT:
result = execute_return_statement(inter, env, statement);
break;
case BREAK_STATEMENT:
result = execute_break_statement(inter, env, statement);
break;
case CONTINUE_STATEMENT:
result = execute_continue_statement(inter, env, statement);
break;
case THROW_STATEMENT:
result = execute_throw_statement(inter, env, statement);
break;
case STATEMENT_TYPE_COUNT_PLUS_1: /* FALLTHRU */
default:
DBG_panic(("bad case...%d", statement->type));
}
return result;
}
StatementResult
wj_execute_statement_list(WJ_Interpreter *inter, WJ_LocalEnvironment *env,
StatementList *list)
{
StatementList *pos;
StatementResult result;
result.type = NORMAL_STATEMENT_RESULT;
for (pos = list; pos; pos = pos->next) {
result = execute_statement(inter, env, pos->statement);
if (result.type != NORMAL_STATEMENT_RESULT)
goto FUNC_END;
}
FUNC_END:
return result;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。