📄 funcs.c
字号:
/* "p2c", a Pascal to C translator. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation. Author's address: daveg@synaptics.com.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation (any version).This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; see the file COPYING. If not, write tothe Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#define PROTO_FUNCS_C#include "trans.h"Static Strlist *enumnames;Static int enumnamecount;void setup_funcs(){ enumnames = NULL; enumnamecount = 0;}int isvar(ex, mp)Expr *ex;Meaning *mp;{ return (ex->kind == EK_VAR && (Meaning *)ex->val.i == mp);}char *getstring(ex)Expr *ex;{ ex = makeexpr_stringify(ex); if (ex->kind != EK_CONST || ex->val.type->kind != TK_STRING) { intwarning("getstring", "Not a string literal [206]"); return ""; } return ex->val.s;}Expr *p_parexpr(target)Type *target;{ Expr *ex; if (wneedtok(TOK_LPAR)) { ex = p_expr(target); if (!wneedtok(TOK_RPAR)) skippasttotoken(TOK_RPAR, TOK_SEMI); } else ex = p_expr(target); return ex;}Type *argbasetype(ex)Expr *ex;{ if (ex->kind == EK_CAST) ex = ex->args[0]; if (ex->val.type->kind == TK_POINTER) return ex->val.type->basetype; else return ex->val.type;}Type *choosetype(t1, t2)Type *t1, *t2;{ if (t1 == tp_void || (type_sizeof(t2, 1) && !type_sizeof(t1, 1))) return t2; else return t1;}Expr *convert_offset(type, ex2)Type *type;Expr *ex2;{ long size; int i; Value val; Expr *ex3; if (type->kind == TK_POINTER || type->kind == TK_ARRAY || type->kind == TK_SET || type->kind == TK_STRING) type = type->basetype; size = type_sizeof(type, 1); if (size == 1) return ex2; val = eval_expr_pasc(ex2); if (val.type) { if (val.i == 0) return ex2; if (size && val.i % size == 0) { freeexpr(ex2); return makeexpr_long(val.i / size); } } else { /* look for terms like "n*sizeof(foo)" */ while (ex2->kind == EK_CAST || ex2->kind == EK_ACTCAST) ex2 = ex2->args[0]; if (ex2->kind == EK_TIMES) { for (i = 0; i < ex2->nargs; i++) { ex3 = convert_offset(type, ex2->args[i]); if (ex3) { ex2->args[i] = ex3; return resimplify(ex2); } } for (i = 0; i < ex2->nargs && ex2->args[i]->kind != EK_SIZEOF; i++) ; if (i < ex2->nargs) { if (ex2->args[i]->args[0]->val.type == type) { delfreearg(&ex2, i); if (ex2->nargs == 1) return ex2->args[0]; else return ex2; } } } else if (ex2->kind == EK_PLUS) { ex3 = copyexpr(ex2); for (i = 0; i < ex2->nargs; i++) { ex3->args[i] = convert_offset(type, ex3->args[i]); if (!ex3->args[i]) { freeexpr(ex3); return NULL; } } freeexpr(ex2); return resimplify(ex3); } else if (ex2->kind == EK_SIZEOF) { if (ex2->args[0]->val.type == type) { freeexpr(ex2); return makeexpr_long(1); } } else if (ex2->kind == EK_NEG) { ex3 = convert_offset(type, ex2->args[0]); if (ex3) return makeexpr_neg(ex3); } } return NULL;}Expr *convert_size(type, ex, name)Type *type;Expr *ex;char *name;{ long size; Expr *ex2; int i, okay; Value val; if (debug>2) { fprintf(outf,"convert_size("); dumpexpr(ex); fprintf(outf,")\n"); } while (type->kind == TK_ARRAY || type->kind == TK_STRING) type = type->basetype; if (type == tp_void) return ex; size = type_sizeof(type, 1); if (size == 1) return ex; while (ex->kind == EK_CAST || ex->kind == EK_ACTCAST) ex = ex->args[0]; switch (ex->kind) { case EK_TIMES: for (i = 0; i < ex->nargs; i++) { ex2 = convert_size(type, ex->args[i], NULL); if (ex2) { ex->args[i] = ex2; return resimplify(ex); } } break; case EK_PLUS: okay = 1; for (i = 0; i < ex->nargs; i++) { ex2 = convert_size(type, ex->args[i], NULL); if (ex2) ex->args[i] = ex2; else okay = 0; } ex = distribute_plus(ex); if ((ex->kind != EK_TIMES || !okay) && name) note(format_s("Suspicious mixture of sizes in %s [173]", name)); return ex; case EK_SIZEOF: return ex; default: break; } val = eval_expr_pasc(ex); if (val.type) { if (val.i == 0) return ex; if (size && val.i % size == 0) { freeexpr(ex); return makeexpr_times(makeexpr_long(val.i / size), makeexpr_sizeof(makeexpr_type(type), 0)); } } if (name) { note(format_s("Can't interpret size in %s [174]", name)); return ex; } else return NULL;}Static Expr *func_abs(){ Expr *ex; Meaning *tvar; int lness; ex = p_parexpr(tp_integer); if (ex->val.type->kind == TK_REAL) return makeexpr_bicall_1("fabs", tp_longreal, ex); else { lness = exprlongness(ex); if (lness < 0) return makeexpr_bicall_1("abs", tp_int, ex); else if (lness > 0 && *absname) { if (ansiC > 0) { return makeexpr_bicall_1("labs", tp_integer, ex); } else if (*absname == '*' && (exprspeed(ex) >= 5 || !nosideeffects(ex, 0))) { tvar = makestmttempvar(tp_integer, name_TEMP); return makeexpr_comma(makeexpr_assign(makeexpr_var(tvar), ex), makeexpr_bicall_1(absname, tp_integer, makeexpr_var(tvar))); } else { return makeexpr_bicall_1(absname, tp_integer, ex); } } else if (exprspeed(ex) < 5 && nosideeffects(ex, 0)) { return makeexpr_cond(makeexpr_rel(EK_LT, copyexpr(ex), makeexpr_long(0)), makeexpr_neg(copyexpr(ex)), ex); } else { tvar = makestmttempvar(tp_integer, name_TEMP); return makeexpr_cond(makeexpr_rel(EK_LT, makeexpr_assign(makeexpr_var(tvar), ex), makeexpr_long(0)), makeexpr_neg(makeexpr_var(tvar)), makeexpr_var(tvar)); } }}Static Expr *func_addr(){ Expr *ex, *ex2, *ex3; Type *type, *tp2; int haspar; haspar = wneedtok(TOK_LPAR); ex = p_expr(tp_proc); if (curtok == TOK_COMMA) { gettok(); ex2 = p_expr(tp_integer); ex3 = convert_offset(ex->val.type, ex2); if (checkconst(ex3, 0)) { ex = makeexpr_addrf(ex); } else { ex = makeexpr_addrf(ex); if (ex3) { ex = makeexpr_plus(ex, ex3); } else { note("Don't know how to reduce offset for ADDR [175]"); type = makepointertype(tp_abyte); tp2 = ex->val.type; ex = makeexpr_cast(makeexpr_plus(makeexpr_cast(ex, type), ex2), tp2); } } } else { if ((ex->val.type->kind != TK_PROCPTR && ex->val.type->kind != TK_CPROCPTR) || (ex->kind == EK_VAR && ex->val.type == ((Meaning *)ex->val.i)->type)) ex = makeexpr_addrf(ex); } if (haspar) { if (!wneedtok(TOK_RPAR)) skippasttotoken(TOK_RPAR, TOK_SEMI); } return ex;}Static Expr *func_iaddress(){ return makeexpr_cast(func_addr(), tp_integer);}Static Expr *func_addtopointer(){ Expr *ex, *ex2, *ex3; Type *type, *tp2; if (!skipopenparen()) return NULL; ex = p_expr(tp_anyptr); if (skipcomma()) { ex2 = p_expr(tp_integer); } else ex2 = makeexpr_long(0); skipcloseparen(); ex3 = convert_offset(ex->val.type, ex2); if (!checkconst(ex3, 0)) { if (ex3) { ex = makeexpr_plus(ex, ex3); } else { note("Don't know how to reduce offset for ADDTOPOINTER [175]"); type = makepointertype(tp_abyte); tp2 = ex->val.type; ex = makeexpr_cast(makeexpr_plus(makeexpr_cast(ex, type), ex2), tp2); } } return ex;}Stmt *proc_assert(){ Expr *ex; ex = p_expr(tp_boolean); return makestmt_call(makeexpr_bicall_1("assert", tp_void, ex));}Stmt *wrapopencheck(sp, fex)Stmt *sp;Expr *fex;{ Stmt *sp2; if (FCheck(checkfileisopen) && !is_std_file(fex)) { sp2 = makestmt(SK_IF); sp2->exp1 = makeexpr_rel(EK_NE, filebasename(fex), makeexpr_nil()); sp2->stm1 = sp; if (iocheck_flag) { sp2->stm2 = makestmt_call(makeexpr_bicall_1(name_ESCIO, tp_integer, makeexpr_name(filenotopenname, tp_int))); } else { sp2->stm2 = makestmt_assign(makeexpr_var(mp_ioresult), makeexpr_name(filenotopenname, tp_int)); } return sp2; } else { freeexpr(fex); return sp; }}Static Expr *checkfilename(nex)Expr *nex;{ Expr *ex; nex = makeexpr_stringcast(nex); if (nex->kind == EK_CONST && nex->val.type->kind == TK_STRING) { switch (which_lang) { case LANG_HP: if (!strncmp(nex->val.s, "#1:", 3) || !strncmp(nex->val.s, "console:", 8) || !strncmp(nex->val.s, "CONSOLE:", 8)) { freeexpr(nex); nex = makeexpr_string("/dev/tty"); } else if (!strncmp(nex->val.s, "#2:", 3) || !strncmp(nex->val.s, "systerm:", 8) || !strncmp(nex->val.s, "SYSTERM:", 8)) { freeexpr(nex); nex = makeexpr_string("/dev/tty"); /* should do more? */ } else if (!strncmp(nex->val.s, "#6:", 3) || !strncmp(nex->val.s, "printer:", 8) || !strncmp(nex->val.s, "PRINTER:", 8)) { note("Opening a file named PRINTER: [176]"); } else if (my_strchr(nex->val.s, ':')) { note("Opening a file whose name contains a ':' [177]"); } break; case LANG_TURBO: if (checkstring(nex, "con") || checkstring(nex, "CON") || checkstring(nex, "")) { freeexpr(nex); nex = makeexpr_string("/dev/tty"); } else if (checkstring(nex, "nul") || checkstring(nex, "NUL")) { freeexpr(nex); nex = makeexpr_string("/dev/null"); } else if (checkstring(nex, "lpt1") || checkstring(nex, "LPT1") || checkstring(nex, "lpt2") || checkstring(nex, "LPT2") || checkstring(nex, "lpt3") || checkstring(nex, "LPT3") || checkstring(nex, "com1") || checkstring(nex, "COM1") || checkstring(nex, "com2") || checkstring(nex, "COM2")) { note("Opening a DOS device file name [178]"); } break; default: break; } } else { if (*filenamefilter && strcmp(filenamefilter, "0")) { ex = makeexpr_sizeof(copyexpr(nex), 0); nex = makeexpr_bicall_2(filenamefilter, tp_str255, nex, ex); } else nex = makeexpr_stringify(nex); } return nex;}Static Stmt *assignfilename(fex, nex)Expr *fex, *nex;{ Meaning *mp; Expr *nvex; nvex = filenamepart(fex); if (nvex) { freeexpr(fex); return makestmt_call(makeexpr_assign(nvex, nex)); } else { mp = isfilevar(fex); if (mp) warning("Don't know how to ASSIGN to a non-explicit file variable [207]"); else note("Encountered an ASSIGN statement [179]"); return makestmt_call(makeexpr_bicall_2("assign", tp_void, fex, nex)); }}Static Stmt *proc_assign(){ Expr *fex, *nex; if (!skipopenparen()) return NULL; fex = p_expr(tp_text); if (!skipcomma()) return NULL; nex = checkfilename(p_expr(tp_str255)); skipcloseparen(); return assignfilename(fex, nex);}Static Stmt *handleopen(code)int code;{ Stmt *sp, *sp1, *sp2, *spassign; Expr *fex, *tfex, *nex, *ex, *truenex, *nvex; Meaning *fmp; int needcheckopen = 1; char modebuf[5], *cp; if (!skipopenparen()) return NULL; fex = p_expr(tp_text); tfex = fex; fmp = isfilevar(fex); nvex = filenamepart(fex); truenex = NULL; spassign = NULL; if (curtok == TOK_COMMA) { gettok(); ex = p_expr(tp_str255); } else ex = NULL; if (ex && (ex->val.type->kind == TK_STRING || ex->val.type->kind == TK_ARRAY)) { nex = checkfilename(ex); if (nvex) { spassign = assignfilename(copyexpr(fex), nex); nex = nvex; } truenex = nex; if (curtok == TOK_COMMA) { gettok();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -