static void ICACHE_FLASH_ATTR check_match (LexState *ls, int what, int who, int where) { if (!testnext(ls, what)) { if (where == ls->linenumber) error_expected(ls, what); else { luaX_syntaxerror(ls, luaO_pushfstring(ls->L, LUA_QS " expected (to close " LUA_QS " at line %d)", luaX_token2str(ls, what), luaX_token2str(ls, who), where)); } } }
static void check_match (LexState *ls, int what, int who, int where) { if (!testnext(ls, what)) { if (where == ls->linenumber) error_expected(ls, what); else { luaX_syntaxerror(ls, luaO_pushfstring(ls->L, "%s expected (to close %s at line %d)", luaX_token2str(ls, what), luaX_token2str(ls, who), where)); } } }
/*static*/ void LexState::check_match (/*LexState *ls,*/ int what, int who, int where) { if (!testnext(what)) { if (where == linenumber) error_expected(what); else { luaX_syntaxerror( luaO_pushfstring(L, "%s expected (to close %s at line %d)", luaX_token2str(what), luaX_token2str(who), where)); } } }
static void check_match(ktap_lexstate *ls, int what, int who, int where) { if (!testnext(ls, what)) { if (where == ls->linenumber) error_expected(ls, what); else { lex_syntaxerror(ls, ktapc_sprintf( "%s expected (to close %s at line %d)", lex_token2str(ls, what), lex_token2str(ls, who), where)); } } }
void exec_while(env_t* env, ast_t* ast) { ast_t* cond = eval_expression(env, ast->data.while_statement.condition); if(cond->type != at_bool) { error_expected(NULL,get_ast_type_name(at_bool),get_ast_type_name(cond->type)); } else { while(cond->data.b) { exec_statements(env, ast->data.while_statement.statements); dec_ref(cond); cond = eval_expression(env, ast->data.while_statement.condition); } dec_ref(cond); } }
void exec_dowhile(env_t* env, ast_t* ast) { /* same as exec_while() but with a call of exec_statements() before. */ exec_statements(env, ast->data.while_statement.statements); ast_t* cond = eval_expression(env, ast->data.while_statement.condition); if(cond->type != at_bool) { error_expected(NULL,get_ast_type_name(at_bool),get_ast_type_name(cond->type)); } else { while(cond->data.b) { exec_statements(env, ast->data.while_statement.statements); dec_ref(cond); cond = eval_expression(env, ast->data.while_statement.condition); } dec_ref(cond); } }
int exec_if(env_t* env, ast_t* ast) { int result = 0; /* not null when condition was true, null when condition was false */ ast_t* cond = eval_expression(env, ast->data.if_statement.condition); if(cond->type != at_bool) { error_expected(NULL,get_ast_type_name(at_bool),get_ast_type_name(cond->type)); } else { if(cond->data.b) { exec_statements(env, ast->data.if_statement.statements); result = 1; } dec_ref(cond); } return result; }
static void check_match (LexState *ls, int what, int who, int where) { if (ls->t.token != what) { if (where == ls->linenumber) error_expected(ls, what); else { char buff[100]; char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; luaX_token2str(what, t_what); luaX_token2str(who, t_who); sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", t_what, t_who, where); luaK_error(ls, buff); } } next(ls); }
static void check (LexState *ls, int c) { if (ls->t.token != c) error_expected(ls, c); }
static void check (LexState *ls, int c) { if (!testnext(ls, c)) error_expected(ls, c); }
static void check(ktap_lexstate *ls, int c) { if (ls->t.token != c) error_expected(ls, c); }
ast_t* eval_call(env_t* env, ast_t* ast) { ast_t* func = NULL; ast_t* result = NULL; char* fn = NULL; /* function name */ switch(ast->data.call.call_type) { case ct_anonymous: fn = "<anonymous>"; func = ast->data.call.function.function; break; case ct_named: fn = ast->data.call.function.id; func = get_ast_by_id(env, fn); if(func == NULL) { error_id(NULL, fn); }; break; } switch(func->type) { case at_function:{ size_t i; if(ast->data.call.callargs->data.callargs.count != func->data.function.params->data.params.count) { error_paramcount(NULL, fn, func->data.function.params->data.params.count, ast->data.call.callargs->data.callargs.count); } env_t* inner = create_env(); inner->parent = env; for(i = 0; i < func->data.function.params->data.params.count; i++) { set_ast_to_id( inner, func->data.function.params->data.params.params[i], eval_expression(env,ast->data.call.callargs->data.callargs.callargs[i]) ); } /* execute the function */ exec_statements(inner, func->data.function.statements); /* get the result */ inner->parent = NULL; /* must be NULL, get_ast_by_id() also searches the parent environment */ result = get_ast_by_id(inner, "@"); free_env(inner); break; } case at_builtin: if(ast->data.call.callargs->data.callargs.count != func->data.builtin.paramcount) { error_paramcount(NULL, fn, func->data.function.params->data.params.count, ast->data.call.callargs->data.callargs.count); } switch(func->data.builtin.paramcount) { case 0: result = func->data.builtin.function.builtin_0(); break; case 1: { ast_t* p = eval_expression(env,ast->data.call.callargs->data.callargs.callargs[0]); result = func->data.builtin.function.builtin_1(p); dec_ref(p); break; } case 2: { ast_t* p1 = eval_expression(env,ast->data.call.callargs->data.callargs.callargs[0]); ast_t* p2 = eval_expression(env,ast->data.call.callargs->data.callargs.callargs[1]); result = func->data.builtin.function.builtin_2(p1,p2); dec_ref(p1); dec_ref(p2); break; } case 3: { ast_t* p1 = eval_expression(env, ast->data.call.callargs->data.callargs.callargs[0]); ast_t* p2 = eval_expression(env, ast->data.call.callargs->data.callargs.callargs[1]); ast_t* p3 = eval_expression(env, ast->data.call.callargs->data.callargs.callargs[2]); result = func->data.builtin.function.builtin_3(p1,p2,p3); dec_ref(p1); dec_ref(p2); dec_ref(p3); break; } default: printf("\n\n*** HINT TO DEVELOPER ***\nimplement builtincall in vm.c\n\n"); exit(1); /* if you create a builtin function with more parameters then you have to add a case here */ break; } break; default: error_expected(NULL, get_ast_type_name(at_function), get_ast_type_name(func->type)); break; } return result; }
ast_t* eval_expression(env_t* env, ast_t* ast) { switch(ast->type) { /* valid */ case at_call: return eval_call(env,ast); case at_identifier: return get_ast_by_id(env, ast->data.id); case at_expression: { ast_t* result = NULL; ast_t* left = eval_expression(env, ast->data.expression.left); ast_t* right = eval_expression(env, ast->data.expression.right); inc_ref(left); inc_ref(right); switch(ast->data.expression.op) { case op_add: result = eval_add(env, left, right); break; case op_mul: result = eval_mul(env, left, right); break; case op_div: result = eval_div(env, left, right); break; case op_sub: result = eval_sub(env, left, right); break; case op_mod: result = eval_mod(env, left, right); break; case op_and: result = eval_and(env, left, right); break; case op_or: result = eval_or(env, left, right); break; case op_gt: result = eval_gt(env, left, right); break; case op_ge: result = eval_ge(env, left, right); break; case op_lt: result = eval_lt(env, left, right); break; case op_le: result = eval_le(env, left, right); break; case op_eq: result = eval_eq(env, left, right); break; case op_neq: result = eval_neq(env, left, right); break; case op_cat: result = eval_cat(env, left, right); break; case op_deref: { ast_t* index = eval_expression(env, right); if (index->type != at_integer) { // TODO: error -> index must be an integer! } else { switch(left->type) { case at_list: result = left->data.list.elements[index->data.i]; } } } } result->ref_count = 0; dec_ref(left); dec_ref(right); return result; } /* no need to evaluate */ case at_integer: case at_bool: case at_double: case at_string: case at_function: case at_statements: case at_list: return ast; /* invalid */ case at_assignment: case at_callargs: case at_conditional: case at_dowhile: case at_elif: case at_if: case at_params: case at_while: case at_builtin: error_expected(NULL,"expression",get_ast_type_name(ast->type)); } return NULL; /* this should never happen */ }
static void ICACHE_FLASH_ATTR check (LexState *ls, int c) { if (ls->t.token != c) error_expected(ls, c); }
/*static*/ void LexState::check (/*LexState *ls,*/ int c) { if (t.token != c) error_expected(c); }