📄 x86dos.c
字号:
}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 + -