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

📄 x86dos.c

📁 浙江大学编译原理课程设计源代码,高等院校计算机专业
💻 C
📖 第 1 页 / 共 4 页
字号:
}static int localvariable(Symbol symbol){    return 0;}static int deflabel(Symbol symbol){    return 0;}static int defaddress(Symbol p, Symbol q, long n){    return 0;}static int defconst(int type, Value value){    return 0;}static int allocspace(int n){    return n;}static int marknode(Node rootnode){    return 0;}static int gen_dos_code(Node rootnode){    int ret = 0;    Node pnode;    gen_level++;    switch (generic(rootnode->op))    {    case ARG:        if (!rootnode->kids[0])        {            return ERROR_SUCCESS;        }        gen_dos_code(rootnode->kids[0]);        do_dos_first_arg(rootnode->kids[0]->type->type_id);        pnode = rootnode->kids[1];        while(pnode)        {            if (!pnode->kids[0])                break;            gen_dos_code(pnode->kids[0]);            do_dos_args(pnode->kids[0]->type->type_id);            pnode = pnode->kids[1];        }        gen_level --;        return ERROR_SUCCESS;    case AND:    case OR:    case EQ:    case NE:    case GT:    case GE:    case LE:    case LT:        if (rootnode->kids[0])        {            ret = gen_dos_code(rootnode->kids[0]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        emit_dos_dos_push_op(rootnode->kids[0]->type);        if (rootnode->kids[1])        {            ret = gen_dos_code(rootnode->kids[1]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        break;    case BOR:    case BAND:    case BXOR:    case ADD:    case SUB:        if (rootnode->kids[0])        {            ret = gen_dos_code(rootnode->kids[0]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        emit_dos_dos_push_op(rootnode->kids[0]->type);        if (rootnode->kids[1])        {            ret = gen_dos_code(rootnode->kids[1]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        break;    case RSH:    case LSH:    case DIV:    case MUL:    case MOD:        if (rootnode->kids[0])        {            ret = gen_dos_code(rootnode->kids[0]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        emit_dos_dos_push_op(rootnode->kids[0]->type);        if (rootnode->kids[1])        {            ret = gen_dos_code(rootnode->kids[1]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        break;    case ARRAY:        emit_dos_load_address(rootnode->syms[0]);        emit_dos_dos_push_op(find_type_by_id(TYPE_INTEGER));        if (rootnode->kids[0])        {            ret = gen_dos_code(rootnode->kids[0]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        break;        /*        case ADDRG:        if (rootnode->kids[0] != NULL)        {        	if (generic(rootnode->kids[0]->op) == ARRAY)        	{        		emit_dos_load_address(rootnode->kids[0]->syms[0]);        		emit_dos_dos_push_op(TYPE_INTEGER);        	}        	else if (generic(rootnode->kids[0]->op) == FIELD)        	{        		emit_dos_load_address(rootnode->syms[0]);        		emit_dos_dos_push_op(TYPE_INTEGER);        		do_dos_record_factor(rootnode->syms[0], rootnode->syms[1]);        	}        }        break;        */    case SYS:        /* for sys call, all childnodes will be processed in next switch. */        break;    case CALL:        push_call_stack(rootnode->symtab);    default:        if (rootnode->kids[0])        {            ret = gen_dos_code(rootnode->kids[0]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        if (rootnode->kids[1])        {            ret = gen_dos_code(rootnode->kids[1]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        if (rootnode->kids[2])        {            ret = gen_dos_code(rootnode->kids[2]);            if (ret < 0)            {                gen_level --;                return ret;            }        }        break;    }    switch (generic(rootnode->op))    {    case ARRAY:        do_dos_array_factor(rootnode->syms[0]);        break;    case CNST:        do_dos_factor(rootnode->syms[0]);        break;    case FIELD:        emit_dos_load_address(rootnode->syms[0]);        emit_dos_dos_push_op(find_type_by_id(TYPE_INTEGER));        do_dos_record_factor(rootnode->syms[0], rootnode->syms[1]);        /* emit_dos_load_field(rootnode->syms[1]); */        break;    case HEADER:        emit_dos_routine_prologue(rootnode->symtab);        break;    case TAIL:        emit_dos_routine_epilogue(rootnode->symtab);        break;    case NOT:        do_dos_not_factor(rootnode->kids[0]->syms[0]);        break;    case NEG:        do_dos_negate(rootnode->kids[0]->syms[0]);        break;    case ASGN:        {            p = rootnode->kids[0]->syms[0];            if (!p)                assert(0);            if (p->defn == DEF_FUNCT)            {                ptab = find_routine(p->name);                if(ptab)                    do_dos_function_assign(ptab, rootnode->kids[0]->type->type_id);                else                {                    parse_error("Undeclared identifier.", p->name);                    gen_level --;                    return ERROR_UNDECLARE;                }            }            else            {                do_dos_assign(p, rootnode->kids[0]->type->type_id);            }        }        break;    case CALL:        do_dos_procedure_call(rootnode->symtab);        pop_call_stack();        break;    case SYS:        emit_dos_address = 1;		/* signal the ADDRG to generate address. */        if ((rootnode->kids[0] == NULL) ||                (rootnode->kids[0]->kids[0] == NULL) ||                (rootnode->kids[0]->kids[1] == NULL))        {            /* do system call without args, or with only one arg. */            if (rootnode->kids[0])			{                if (rootnode->kids[0]->kids[0])                    gen_dos_code(rootnode->kids[0]->kids[0]);                else                    gen_dos_code(rootnode->kids[0]);			}            do_dos_sys_routine(rootnode->u.sys_id, rootnode->kids[0]->type->type_id);        }        else        {#if DEBUG & SYSTEM_CALL_DEBUG            {                Symtab systab = find_sys_routine(rootnode->u.sys_id);                printf("do system call %s with more than one arg.\n", systab->name);            }#endif            switch (rootnode->u.sys_id)            {            case pREAD:            case pREADLN:            case pWRITE:            case pWRITELN:            default:                gen_dos_code(rootnode->kids[0]->kids[0]);                do_dos_sys_routine(rootnode->u.sys_id, rootnode->kids[0]->kids[0]->type->type_id);                pnode = rootnode->kids[0]->kids[1];                while(pnode)                {                    if (!pnode->kids[0])                        break;                    gen_dos_code(pnode->kids[0]);                    do_dos_sys_routine(rootnode->u.sys_id, pnode->kids[0]->type->type_id);                    pnode = pnode->kids[1];                }                break;            }        }        emit_dos_address = 0;		/* clear signal */        break;    case COND:        do_dos_cond_jump(rootnode->u.cond.true_or_false, rootnode->u.cond.label);        break;    case JUMP:        do_dos_jump(rootnode->syms[0]);        break;    case LABEL:        do_dos_label(rootnode->syms[0]);        break;    case INCR:        /*         * variable is in first child of INCR node.         * generally an ADDRG node.         */        assert(rootnode->kids[0]->syms[0]);        do_dos_incr(rootnode->kids[0]->syms[0]);        break;    case DECR:        /*         * variable is in first child of DECR node.         * generally an ADDRG node.         */        assert(rootnode->kids[0]->syms[0]);        do_dos_decr(rootnode->kids[0]->syms[0]);        break;    case LOAD:        if (rootnode->kids[0] == NULL)        {            /* simple const or id. */            do_dos_factor(rootnode->syms[0]);        }        else if (generic(rootnode->kids[0]->op) == ARRAY)        {            emit_dos_load_value(rootnode->kids[0]->syms[0]);        }        else        {            emit_dos_load_field(rootnode->kids[0]->syms[1]);        }        break;    case EQ:    case NE:    case GT:    case GE:    case LE:    case LT:        do_dos_expression(rootnode->kids[1]->type, rootnode->op);        break;    case ADD:    case SUB:    case OR:        do_dos_expr(rootnode->kids[1]->type, rootnode->op);        break;    case AND:    case RSH:    case LSH:    case BOR:    case BAND:    case BXOR:    case DIV:    case MUL:    case MOD:        /*        if (rootnode->kids[0])        {        	ret = gen_dos_code(rootnode->kids[0]);        	if (ret < 0) {        		gen_level --;        		return ret;        	}        }        */        do_dos_term(rootnode->kids[1]->type, rootnode->op);        break;    case BLOCKBEG:    case BLOCKEND:        break;    case ADDRG:        if (emit_dos_address)            emit_dos_load_address(rootnode->syms[0]);        break;    default:        assert(0);        break;    }    gen_level --;    return ret;}static int functionprocess(List dags){    List cp = dags->link;    int ret = 0;    for (; cp; cp = cp->link)    {        if ((ret = gen_dos_code((Node)(cp->x))) < 0)        {            parse_error("Error generating code.","");            return ret;        }    }    return ret;}static int blockbegin(BlockContext *context){    return 0;}static int blockend(BlockContext *context){    return 0;}static void defexport(Symbol sym){}static void defimport(Symbol sym){}Interface x86_dos_interface = {  /* type interface */  {1, 1, 0},		/* charmetric */  {2, 2, 0},		/* shortmetric */  {2, 2, 0},		/* intmetric */  {4, 4, 0},		/* floatmetric */  {8, 8, 0},		/* doublemetric */  {4, 4, 0},		/* pointermetric */  {4, 4, 0},		/* structmetric */  /* function interface. */  programbegin,  programend,  mainbegin,  mainend,  defaddress,  blockbegin,  blockend,  globalvariable,  localvariable,  deflabel,  defconst,  allocspace,  marknode,  gen_dos_code,  functionprocess,  defexport,  defimport,};

⌨️ 快捷键说明

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