// Handle a uri command static bool uri_command(pass_opt_t* opt, ast_t* ast, ast_t* uri, ast_t* alias, ast_t* guard) { assert(uri != NULL); assert(alias != NULL); assert(guard != NULL); const char* locator; int index = find_handler(opt, uri, &locator); if(index < 0) // Scheme not found return false; if(ast_id(alias) != TK_NONE && !handlers[index].allow_name) { ast_error(opt->check.errors, alias, "Use scheme %s may not have an alias", handlers[index].scheme); return false; } if(ast_id(guard) != TK_NONE && !handlers[index].allow_guard) { ast_error(opt->check.errors, alias, "Use scheme %s may not have a guard", handlers[index].scheme); return false; } if(ifdef_cond_normalise(&guard, opt) && !ifdef_cond_eval(guard, opt)) return true; assert(handlers[index].handler != NULL); return handlers[index].handler(ast, locator, alias, opt); }
static ast_result_t sugar_ifdef(typecheck_t* t, ast_t* ast) { assert(t != NULL); assert(ast != NULL); AST_GET_CHILDREN(ast, cond, then_block, else_block, else_cond); // Combine parent ifdef condition with ours. ast_t* parent_ifdef_cond = t->frame->ifdef_cond; if(parent_ifdef_cond != NULL) { // We have a parent ifdef, combine its condition with ours. assert(ast_id(ast_parent(parent_ifdef_cond)) == TK_IFDEF); REPLACE(&else_cond, NODE(TK_AND, TREE(parent_ifdef_cond) NODE(TK_NOT, TREE(cond)))); REPLACE(&cond, NODE(TK_AND, TREE(parent_ifdef_cond) TREE(cond))); } else { // Make else condition for our children to use. REPLACE(&else_cond, NODE(TK_NOT, TREE(cond))); } // Normalise condition so and, or and not nodes aren't sugared to function // calls. if(!ifdef_cond_normalise(&cond)) { ast_error(ast, "ifdef condition will never be true"); return AST_ERROR; } if(!ifdef_cond_normalise(&else_cond)) { ast_error(ast, "ifdef condition is always true"); return AST_ERROR; } return sugar_else(ast); }
static ast_result_t sugar_use(ast_t* ast) { assert(ast != NULL); // Normalise condition so and, or and not nodes aren't sugared to function // calls. ast_t* guard = ast_childidx(ast, 2); if(!ifdef_cond_normalise(&guard)) { ast_error(ast, "use guard condition will never be true"); return AST_ERROR; } return AST_OK; }