⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsstree.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
        ws_error_memory(compiler);        return;    }    if (hash->defined) {        ws_src_error(compiler, line, "redefinition of `%s'", name);        ws_src_error(compiler,                     compiler->functions[hash->findex].line,                     "`%s' previously defined here", name);        return;    }    hash->defined = WS_TRUE;    hash->findex = f->findex;}/********************* Expressions **************************************/void ws_expr_linearize(WsCompiler *compiler, WsExpression *expr){    WsListItem *li;    WsAsmIns *ins;    switch (expr->type) {    case WS_EXPR_COMMA:        /* Linearize left. */        ws_expr_linearize(compiler, expr->u.comma.left);        /* Pop its result. */        ws_asm_link(compiler, ws_asm_ins(compiler, expr->line, WS_ASM_POP));        /* Linearize right */        ws_expr_linearize(compiler, expr->u.comma.right);        break;    case WS_EXPR_ASSIGN:        {            WsNamespace *ns = ws_variable_lookup(compiler,                                                 expr->u.assign.identifier);            if (ns == NULL) {                /* Unknown identifier. */                ws_src_error(compiler, expr->line, "unknown variable `%s'",                             expr->u.symbol);                return;            }            if (expr->u.assign.op == '=') {                /* Evaluate the expression. */                ws_expr_linearize(compiler, expr->u.assign.expr);                /* Store the value to the variable. */                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line,                                            WS_ASM_P_STORE_VAR, ns->vindex));            } else if (expr->u.assign.op == tADDA) {                /* Linearize the expression. */                ws_expr_linearize(compiler, expr->u.assign.expr);                /* Add it to the variable. */                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line,                                            WS_ASM_ADD_ASG, ns->vindex));            } else if (expr->u.assign.op == tSUBA) {                /* Linearize the expression. */                ws_expr_linearize(compiler, expr->u.assign.expr);                /* Substract it from the variable. */                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line,                                            WS_ASM_SUB_ASG, ns->vindex));            } else {                /* Load the old value from the variable. */                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line,                                            WS_ASM_P_LOAD_VAR, ns->vindex));                /* Evaluate the expression. */                ws_expr_linearize(compiler, expr->u.assign.expr);                /* Perform the operand. */                ins = NULL;                switch (expr->u.assign.op) {                case tMULA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_MUL);                    break;                case tDIVA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_DIV);                    break;                case tREMA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_REM);                    break;                case tADDA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_ADD);                    break;                case tSUBA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_SUB);                    break;                case tLSHIFTA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_LSHIFT);                    break;                case tRSSHIFTA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_RSSHIFT);                    break;                case tRSZSHIFTA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_RSZSHIFT);                    break;                case tANDA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_AND);                    break;                case tXORA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_XOR);                    break;                case tORA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_B_OR);                    break;                case tIDIVA:                    ins = ws_asm_ins(compiler, expr->line, WS_ASM_IDIV);                    break;                default:                    ws_fatal("ws_expr_linearize(): unknown assignment operand %x",                             expr->u.assign.op);                    break;                }                ws_asm_link(compiler, ins);                /* Store the value to the variable. */                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line,                                            WS_ASM_P_STORE_VAR, ns->vindex));            }            /* The value of the assignment expression is the value               assigned.  So, we must load the value from the variable.               This would also be a good place for the `dup' operand but               we lose since we don't have it. */            ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,                                                  WS_ASM_P_LOAD_VAR, ns->vindex));        }        break;    case WS_EXPR_CONDITIONAL:        {            WsAsmIns *l_else = ws_asm_label(compiler, expr->line);            WsAsmIns *l_end = ws_asm_label(compiler, expr->line);            /* Linearize condition. */            ws_expr_linearize(compiler, expr->u.conditional.e_cond);            /* If the result if false, jump to the else-branch. */            ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,                                                WS_ASM_P_TJUMP, l_else));            /* Linearize the then-expression and jump out. */            ws_expr_linearize(compiler, expr->u.conditional.e_then);            ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,                                                WS_ASM_P_JUMP, l_end));            /* The else-branch. */            ws_asm_link(compiler, l_else);            ws_expr_linearize(compiler, expr->u.conditional.e_else);            /* Insert the end label. */            ws_asm_link(compiler, l_end);        }        break;    case WS_EXPR_LOGICAL:        {            WsAsmIns *l_out = ws_asm_label(compiler, expr->line);            /* Linearize the left-hand size expression. */            ws_expr_linearize(compiler, expr->u.logical.left);            /* Short-circuit check.  The type of the logical expression is                      the short-circuit byte-code operand. */            ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,                                             expr->u.logical.type));            ws_asm_link(compiler, ws_asm_branch(compiler, expr->line,                                                WS_ASM_P_TJUMP, l_out));            /* Linearize the right-hand size expression. */            ws_expr_linearize(compiler, expr->u.logical.right);            /* The result of a logical expression should be boolean.             * Control statements do automatic conversion, but typeof()	     * does not. */            ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,                                         WS_ASM_TOBOOL));            /* Insert the end label. */            ws_asm_link(compiler, l_out);        }        break;    case WS_EXPR_BINARY:        /* Linearize left and right. */        ws_expr_linearize(compiler, expr->u.binary.left);        ws_expr_linearize(compiler, expr->u.binary.right);        /* The type of the binary expression is the byte-code opcode. */        ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,                                         expr->u.binary.type));        break;    case WS_EXPR_UNARY:        /* Linearize the expression. */        ws_expr_linearize(compiler, expr->u.unary.expr);        /* The type of the unary expression is the byte-code opcode. */        ws_asm_link(compiler, ws_asm_ins(compiler, expr->line,                                         expr->u.unary.type));        break;    case WS_EXPR_UNARY_VAR:        {            WsNamespace *ns = ws_variable_lookup(compiler,                                                 expr->u.unary_var.variable);            if (ns == NULL) {                /* An unknown identifier. */                ws_src_error(compiler, expr->line, "unknown variable `%s'",                             expr->u.unary_var.variable);                return;            }            /* First, do the operation. */            if (expr->u.unary_var.addp)                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line, WS_ASM_P_INCR_VAR,                                            ns->vindex));            else                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line, WS_ASM_DECR_VAR,                                            ns->vindex));            /* Second, load the new value of the variable. */            ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,                                                  WS_ASM_P_LOAD_VAR, ns->vindex));        }        break;    case WS_EXPR_POSTFIX_VAR:        {            WsNamespace *ns = ws_variable_lookup(compiler,                                                 expr->u.postfix_var.variable);            if (ns == NULL) {                /* An unknown identifier. */                ws_src_error(compiler, expr->line, "unknown variable `%s'",                             expr->u.postfix_var.variable);                return;            }            /* First, load the old value of the variable. */            ws_asm_link(compiler, ws_asm_variable(compiler, expr->line,                                                  WS_ASM_P_LOAD_VAR, ns->vindex));            /* Second, do the operation. */            if (expr->u.unary_var.addp)                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line, WS_ASM_P_INCR_VAR,                                            ns->vindex));            else                ws_asm_link(compiler,                            ws_asm_variable(compiler, expr->line, WS_ASM_DECR_VAR,                                            ns->vindex));        }        break;    case WS_EXPR_CALL:        /* First, evaluate the arguments. */        for (li = expr->u.call.arguments->head; li; li = li->next)            ws_expr_linearize(compiler, li->data);        /* Second, emit the call instruction. */        switch (expr->u.call.type) {        case ' ': 		/* LocalScriptFunctionCall */            {                WsFunctionHash *f = ws_function_hash(compiler, expr->u.call.name);                if (f == NULL || !f->defined)                {                    ws_src_error(compiler, expr->line,                                 "unknown local function `%s'",                                 expr->u.call.name);                    return;                }                /* Check that the function is called with correct amount                          of arguments. */                if (expr->u.call.arguments->num_items                    != compiler->functions[f->findex].params->num_items)                {                    ws_src_error(compiler, expr->line,                                 "invalid amount of arguments for `%s': "                                 "expected %u, got %u",                                 expr->u.call.name,                                 compiler->functions[f->findex].params->num_items,                                 expr->u.call.arguments->num_items);                    return;                }                /* Emit assembler. */                ws_asm_link(compiler, ws_asm_call(compiler, expr->line,                                                  f->findex));            }            break;        case '#': 		/* ExternalScriptFunctionCall */            {                WsPragmaUse *use = ws_hash_get(compiler->pragma_use_hash,                                               expr->u.call.base);                WsUInt16 findex;                if (use == NULL)                {                    ws_src_error(compiler, expr->line,                                 "unknown external compilation unit `%s'",                                 expr->u.call.base);                    return;                }                /* Insert the function name to the byte-code pool. */                if (!ws_bc_add_const_utf8_string(                        compiler->bc, &findex,                        (unsigned char *) expr->u.call.name,                        strlen(expr->u.call.name)))                {                    ws_error_memory(compiler);                    return;                }                /* Emit assembler. */                ws_asm_link(compiler,                            ws_asm_call_url(compiler, expr->line,                                            findex, use->urlindex,                                            expr->u.call.arguments->num_items));            }            break;        case '.': 		/* LibraryFunctionCall */            {                WsUInt16 lindex;                WsUInt8 findex;                WsUInt8 num_args;                WsBool lindex_found;                WsBool findex_found;                if (!ws_stdlib_function(expr->u.call.base, expr->u.call.name,                                        &lindex, &findex, &num_args,                                        &lindex_found, &findex_found))                {                    if (!lindex_found)                        ws_src_error(compiler, expr->line,                                     "unknown system library `%s'",                                     expr->u.call.base);                    else                        ws_src_error(compiler, expr->line,                                     "unknown library function `%s.%s'",                                     expr->u.call.base, expr->u.call.name);                    return;                }                /* Check the argument count. */                if (expr->u.call.arguments->num_items != num_args)                {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -