funcs.c.1
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:47k
- /* "p2c", a Pascal to C translator.
- Copyright (C) 1989 David Gillespie.
- Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the 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 of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the 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_parexpr(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, 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;
- mp = isfilevar(fex);
- if (mp && mp->namedfile) {
- freeexpr(fex);
- return makestmt_call(makeexpr_assign(makeexpr_name(format_s(name_FNVAR, mp->name),
- tp_str255),
- nex));
- } else {
- 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, *spassign;
- Expr *fex, *nex, *ex;
- Meaning *fmp;
- int storefilename, needcheckopen = 1;
- char modebuf[5], *cp;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- fmp = isfilevar(fex);
- storefilename = (fmp && fmp->namedfile);
- 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 (storefilename) {
- spassign = assignfilename(copyexpr(fex), nex);
- nex = makeexpr_name(format_s(name_FNVAR, fmp->name), tp_str255);
- }
- if (curtok == TOK_COMMA) {
- gettok();
- ex = p_expr(tp_str255);
- } else
- ex = NULL;
- } else if (storefilename) {
- nex = makeexpr_name(format_s(name_FNVAR, fmp->name), tp_str255);
- } else {
- switch (code) {
- case 0:
- if (ex)
- note("Can't interpret name argument in RESET [180]");
- break;
- case 1:
- note("REWRITE does not specify a name [181]");
- break;
- case 2:
- note("OPEN does not specify a name [181]");
- break;
- case 3:
- note("APPEND does not specify a name [181]");
- break;
- }
- nex = NULL;
- }
- if (ex) {
- if (ord_type(ex->val.type)->kind == TK_INTEGER) {
- if (!checkconst(ex, 1))
- note("Ignoring block size in binary file [182]");
- freeexpr(ex);
- } else {
- if (ex->kind == EK_CONST && ex->val.type->kind == TK_STRING) {
- cp = getstring(ex);
- if (strcicmp(cp, "SHARED"))
- note(format_s("Ignoring option string "%s" in open [183]", cp));
- } else
- note("Ignoring option string in open [183]");
- }
- }
- switch (code) {
- case 0: /* reset */
- strcpy(modebuf, "r");
- break;
- case 1: /* rewrite */
- strcpy(modebuf, "w");
- break;
- case 2: /* open */
- strcpy(modebuf, openmode);
- break;
- case 3: /* append */
- strcpy(modebuf, "a");
- break;
- }
- if (!*modebuf) {
- strcpy(modebuf, "r+");
- }
- if (readwriteopen == 2 ||
- (readwriteopen && fex->val.type != tp_text)) {
- if (!my_strchr(modebuf, '+'))
- strcat(modebuf, "+");
- }
- if (fex->val.type != tp_text && binarymode != 0) {
- if (binarymode == 1)
- strcat(modebuf, "b");
- else
- note("Opening a binary file [184]");
- }
- if (!nex && fmp &&
- !is_std_file(fex) &&
- (literalfilesflag == 1 ||
- strlist_cifind(literalfiles, fmp->name))) {
- nex = makeexpr_string(fmp->name);
- }
- if (!nex) {
- if (isvar(fex, mp_output)) {
- note("RESET/REWRITE ignored for file OUTPUT [319]");
- sp = NULL;
- } else {
- sp = makestmt_call(makeexpr_bicall_1("rewind", tp_void,
- copyexpr(fex)));
- if (code == 0 || is_std_file(fex)) {
- sp = wrapopencheck(sp, copyexpr(fex));
- needcheckopen = 0;
- } else
- sp = makestmt_if(makeexpr_rel(EK_NE, copyexpr(fex),
- makeexpr_nil()),
- sp,
- makestmt_assign(copyexpr(fex),
- makeexpr_bicall_0("tmpfile",
- tp_text)));
- }
- } else if (!strcmp(freopenname, "fclose") ||
- !strcmp(freopenname, "fopen")) {
- sp = makestmt_assign(copyexpr(fex),
- makeexpr_bicall_2("fopen", tp_text,
- copyexpr(nex),
- makeexpr_string(modebuf)));
- if (!strcmp(freopenname, "fclose")) {
- sp = makestmt_seq(makestmt_if(makeexpr_rel(EK_NE, copyexpr(fex), makeexpr_nil()),
- makestmt_call(makeexpr_bicall_1("fclose", tp_void,
- copyexpr(fex))),
- NULL),
- sp);
- }
- } else {
- sp = makestmt_assign(copyexpr(fex),
- makeexpr_bicall_3((*freopenname) ? freopenname : "freopen",
- tp_text,
- copyexpr(nex),
- makeexpr_string(modebuf),
- copyexpr(fex)));
- if (!*freopenname) {
- sp = makestmt_if(makeexpr_rel(EK_NE, copyexpr(fex), makeexpr_nil()),
- sp,
- makestmt_assign(copyexpr(fex),
- makeexpr_bicall_2("fopen", tp_text,
- copyexpr(nex),
- makeexpr_string(modebuf))));
- }
- }
- if (code == 2 && !*openmode && nex) {
- sp = makestmt_seq(sp, makestmt_if(makeexpr_rel(EK_EQ, copyexpr(fex), makeexpr_nil()),
- makestmt_assign(copyexpr(fex),
- makeexpr_bicall_2("fopen", tp_text,
- copyexpr(nex),
- makeexpr_string("w+"))),
- NULL));
- }
- if (nex)
- freeexpr(nex);
- if (FCheck(checkfileopen) && needcheckopen) {
- sp = makestmt_seq(sp, makestmt_call(makeexpr_bicall_2("~SETIO", tp_void,
- makeexpr_rel(EK_NE, copyexpr(fex), makeexpr_nil()),
- makeexpr_name(filenotfoundname, tp_int))));
- }
- sp = makestmt_seq(spassign, sp);
- cp = (code == 0) ? resetbufname : setupbufname;
- if (*cp && fmp) /* (may be eaten later, if buffering isn't needed) */
- sp = makestmt_seq(sp,
- makestmt_call(
- makeexpr_bicall_2(cp, tp_void, fex,
- makeexpr_type(fex->val.type->basetype->basetype))));
- else
- freeexpr(fex);
- skipcloseparen();
- return sp;
- }
- Static Stmt *proc_append()
- {
- return handleopen(3);
- }
- Static Expr *func_arccos(ex)
- Expr *ex;
- {
- return makeexpr_bicall_1("acos", tp_longreal, grabarg(ex, 0));
- }
- Static Expr *func_arcsin(ex)
- Expr *ex;
- {
- return makeexpr_bicall_1("asin", tp_longreal, grabarg(ex, 0));
- }
- Static Expr *func_arctan(ex)
- Expr *ex;
- {
- ex = grabarg(ex, 0);
- if (atan2flag && ex->kind == EK_DIVIDE)
- return makeexpr_bicall_2("atan2", tp_longreal,
- ex->args[0], ex->args[1]);
- return makeexpr_bicall_1("atan", tp_longreal, ex);
- }
- Static Expr *func_arctanh(ex)
- Expr *ex;
- {
- return makeexpr_bicall_1("atanh", tp_longreal, grabarg(ex, 0));
- }
- Static Stmt *proc_argv()
- {
- Expr *ex, *aex, *lex;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (skipcomma()) {
- aex = p_expr(tp_str255);
- } else
- return NULL;
- skipcloseparen();
- lex = makeexpr_sizeof(copyexpr(aex), 0);
- aex = makeexpr_addrstr(aex);
- return makestmt_call(makeexpr_bicall_3("P_sun_argv", tp_void,
- aex, lex, makeexpr_arglong(ex, 0)));
- }
- Static Expr *func_asr()
- {
- Expr *ex;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (skipcomma()) {
- if (signedshift == 0 || signedshift == 2) {
- ex = makeexpr_bicall_2("P_asr", ex->val.type, ex,
- p_expr(tp_unsigned));
- } else {
- ex = force_signed(ex);
- ex = makeexpr_bin(EK_RSH, ex->val.type, ex, p_expr(tp_unsigned));
- if (signedshift != 1)
- note("Assuming >> is an arithmetic shift [320]");
- }
- skipcloseparen();
- }
- return ex;
- }
- Static Expr *func_lsl()
- {
- Expr *ex;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (skipcomma()) {
- ex = makeexpr_bin(EK_LSH, ex->val.type, ex, p_expr(tp_unsigned));
- skipcloseparen();
- }
- return ex;
- }
- Static Expr *func_lsr()
- {
- Expr *ex;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (skipcomma()) {
- ex = force_unsigned(ex);
- ex = makeexpr_bin(EK_RSH, ex->val.type, ex, p_expr(tp_unsigned));
- skipcloseparen();
- }
- return ex;
- }
- Static Expr *func_bin()
- {
- note("Using %b for binary printf format [185]");
- return handle_vax_hex(NULL, "b", 1);
- }
- Static Expr *func_binary(ex)
- Expr *ex;
- {
- char *cp;
- ex = grabarg(ex, 0);
- if (ex->kind == EK_CONST) {
- cp = getstring(ex);
- ex = makeexpr_long(my_strtol(cp, NULL, 2));
- insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
- return ex;
- } else {
- return makeexpr_bicall_3("strtol", tp_integer,
- ex, makeexpr_nil(), makeexpr_long(2));
- }
- }
- Static Expr *handle_bitsize(next)
- int next;
- {
- Expr *ex;
- Type *type;
- int lpar;
- long psize;
- lpar = (curtok == TOK_LPAR);
- if (lpar)
- gettok();
- if (curtok == TOK_IDENT && curtokmeaning &&
- curtokmeaning->kind == MK_TYPE) {
- ex = makeexpr_type(curtokmeaning->type);
- gettok();
- } else
- ex = p_expr(NULL);
- type = ex->val.type;
- if (lpar)
- skipcloseparen();
- psize = 0;
- packedsize(NULL, &type, &psize, 0);
- if (psize > 0 && psize < 32 && next) {
- if (psize > 16)
- psize = 32;
- else if (psize > 8)
- psize = 16;
- else if (psize > 4)
- psize = 8;
- else if (psize > 2)
- psize = 4;
- else if (psize > 1)
- psize = 2;
- else
- psize = 1;
- }
- if (psize)
- return makeexpr_long(psize);
- else
- return makeexpr_times(makeexpr_sizeof(ex, 0),
- makeexpr_long(sizeof_char ? sizeof_char : 8));
- }
- Static Expr *func_bitsize()
- {
- return handle_bitsize(0);
- }
- Static Expr *func_bitnext()
- {
- return handle_bitsize(1);
- }
- Static Expr *func_blockread()
- {
- Expr *ex, *ex2, *vex, *sex, *fex;
- Type *type;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- if (!skipcomma())
- return NULL;
- vex = p_expr(NULL);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- if (curtok == TOK_COMMA) {
- gettok();
- sex = p_expr(tp_integer);
- sex = doseek(copyexpr(fex),
- makeexpr_times(sex, makeexpr_long(512)))->exp1;
- } else
- sex = NULL;
- skipcloseparen();
- type = vex->val.type;
- ex = makeexpr_bicall_4("fread", tp_integer,
- makeexpr_addr(vex),
- makeexpr_long(512),
- convert_size(type, ex2, "BLOCKREAD"),
- copyexpr(fex));
- return makeexpr_comma(sex, ex);
- }
- Static Expr *func_blockwrite()
- {
- Expr *ex, *ex2, *vex, *sex, *fex;
- Type *type;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- if (!skipcomma())
- return NULL;
- vex = p_expr(NULL);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- if (curtok == TOK_COMMA) {
- gettok();
- sex = p_expr(tp_integer);
- sex = doseek(copyexpr(fex),
- makeexpr_times(sex, makeexpr_long(512)))->exp1;
- } else
- sex = NULL;
- skipcloseparen();
- type = vex->val.type;
- ex = makeexpr_bicall_4("fwrite", tp_integer,
- makeexpr_addr(vex),
- makeexpr_long(512),
- convert_size(type, ex2, "BLOCKWRITE"),
- copyexpr(fex));
- return makeexpr_comma(sex, ex);
- }
- Static Stmt *proc_blockread()
- {
- Expr *ex, *ex2, *vex, *rex, *fex;
- Type *type;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- if (!skipcomma())
- return NULL;
- vex = p_expr(NULL);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- if (curtok == TOK_COMMA) {
- gettok();
- rex = p_expr(tp_integer);
- } else
- rex = NULL;
- skipcloseparen();
- type = vex->val.type;
- if (rex) {
- ex = makeexpr_bicall_4("fread", tp_integer,
- makeexpr_addr(vex),
- makeexpr_long(1),
- convert_size(type, ex2, "BLOCKREAD"),
- copyexpr(fex));
- ex = makeexpr_assign(rex, ex);
- if (!iocheck_flag)
- ex = makeexpr_comma(ex,
- makeexpr_assign(makeexpr_var(mp_ioresult),
- makeexpr_long(0)));
- } else {
- ex = makeexpr_bicall_4("fread", tp_integer,
- makeexpr_addr(vex),
- convert_size(type, ex2, "BLOCKREAD"),
- makeexpr_long(1),
- copyexpr(fex));
- if (checkeof(fex)) {
- ex = makeexpr_bicall_2(name_SETIO, tp_void,
- makeexpr_rel(EK_EQ, ex, makeexpr_long(1)),
- makeexpr_name(endoffilename, tp_int));
- }
- }
- return wrapopencheck(makestmt_call(ex), fex);
- }
- Static Stmt *proc_blockwrite()
- {
- Expr *ex, *ex2, *vex, *rex, *fex;
- Type *type;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- if (!skipcomma())
- return NULL;
- vex = p_expr(NULL);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- if (curtok == TOK_COMMA) {
- gettok();
- rex = p_expr(tp_integer);
- } else
- rex = NULL;
- skipcloseparen();
- type = vex->val.type;
- if (rex) {
- ex = makeexpr_bicall_4("fwrite", tp_integer,
- makeexpr_addr(vex),
- makeexpr_long(1),
- convert_size(type, ex2, "BLOCKWRITE"),
- copyexpr(fex));
- ex = makeexpr_assign(rex, ex);
- if (!iocheck_flag)
- ex = makeexpr_comma(ex,
- makeexpr_assign(makeexpr_var(mp_ioresult),
- makeexpr_long(0)));
- } else {
- ex = makeexpr_bicall_4("fwrite", tp_integer,
- makeexpr_addr(vex),
- convert_size(type, ex2, "BLOCKWRITE"),
- makeexpr_long(1),
- copyexpr(fex));
- if (FCheck(checkfilewrite)) {
- ex = makeexpr_bicall_2(name_SETIO, tp_void,
- makeexpr_rel(EK_EQ, ex, makeexpr_long(1)),
- makeexpr_name(filewriteerrorname, tp_int));
- }
- }
- return wrapopencheck(makestmt_call(ex), fex);
- }
- Static Stmt *proc_bclr()
- {
- Expr *ex, *ex2;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- skipcloseparen();
- return makestmt_assign(ex,
- makeexpr_bin(EK_BAND, ex->val.type,
- copyexpr(ex),
- makeexpr_un(EK_BNOT, ex->val.type,
- makeexpr_bin(EK_LSH, tp_integer,
- makeexpr_arglong(
- makeexpr_long(1), 1),
- ex2))));
- }
- Static Stmt *proc_bset()
- {
- Expr *ex, *ex2;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- skipcloseparen();
- return makestmt_assign(ex,
- makeexpr_bin(EK_BOR, ex->val.type,
- copyexpr(ex),
- makeexpr_bin(EK_LSH, tp_integer,
- makeexpr_arglong(
- makeexpr_long(1), 1),
- ex2)));
- }
- Static Expr *func_bsl()
- {
- Expr *ex, *ex2;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- skipcloseparen();
- return makeexpr_bin(EK_LSH, tp_integer, ex, ex2);
- }
- Static Expr *func_bsr()
- {
- Expr *ex, *ex2;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- skipcloseparen();
- return makeexpr_bin(EK_RSH, tp_integer, force_unsigned(ex), ex2);
- }
- Static Expr *func_btst()
- {
- Expr *ex, *ex2;
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_integer);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- skipcloseparen();
- return makeexpr_rel(EK_NE,
- makeexpr_bin(EK_BAND, tp_integer,
- ex,
- makeexpr_bin(EK_LSH, tp_integer,
- makeexpr_arglong(
- makeexpr_long(1), 1),
- ex2)),
- makeexpr_long(0));
- }
- Static Expr *func_byteread()
- {
- Expr *ex, *ex2, *vex, *sex, *fex;
- Type *type;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- if (!skipcomma())
- return NULL;
- vex = p_expr(NULL);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- if (curtok == TOK_COMMA) {
- gettok();
- sex = p_expr(tp_integer);
- sex = doseek(copyexpr(fex), sex)->exp1;
- } else
- sex = NULL;
- skipcloseparen();
- type = vex->val.type;
- ex = makeexpr_bicall_4("fread", tp_integer,
- makeexpr_addr(vex),
- makeexpr_long(1),
- convert_size(type, ex2, "BYTEREAD"),
- copyexpr(fex));
- return makeexpr_comma(sex, ex);
- }
- Static Expr *func_bytewrite()
- {
- Expr *ex, *ex2, *vex, *sex, *fex;
- Type *type;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- if (!skipcomma())
- return NULL;
- vex = p_expr(NULL);
- if (!skipcomma())
- return NULL;
- ex2 = p_expr(tp_integer);
- if (curtok == TOK_COMMA) {
- gettok();
- sex = p_expr(tp_integer);
- sex = doseek(copyexpr(fex), sex)->exp1;
- } else
- sex = NULL;
- skipcloseparen();
- type = vex->val.type;
- ex = makeexpr_bicall_4("fwrite", tp_integer,
- makeexpr_addr(vex),
- makeexpr_long(1),
- convert_size(type, ex2, "BYTEWRITE"),
- copyexpr(fex));
- return makeexpr_comma(sex, ex);
- }
- Static Expr *func_byte_offset()
- {
- Type *tp;
- Meaning *mp;
- Expr *ex;
- if (!skipopenparen())
- return NULL;
- tp = p_type(NULL);
- if (!skipcomma())
- return NULL;
- if (!wexpecttok(TOK_IDENT))
- return NULL;
- mp = curtoksym->fbase;
- while (mp && mp->rectype != tp)
- mp = mp->snext;
- if (!mp)
- ex = makeexpr_name(curtokcase, tp_integer);
- else
- ex = makeexpr_name(mp->name, tp_integer);
- gettok();
- skipcloseparen();
- return makeexpr_bicall_2("OFFSETOF", (size_t_long) ? tp_integer : tp_int,
- makeexpr_type(tp), ex);
- }
- Static Stmt *proc_call()
- {
- Expr *ex, *ex2, *ex3;
- Type *type, *tp;
- Meaning *mp;
- if (!skipopenparen())
- return NULL;
- ex2 = p_expr(tp_proc);
- type = ex2->val.type;
- if (type->kind != TK_PROCPTR && type->kind != TK_CPROCPTR) {
- warning("CALL requires a procedure variable [208]");
- type = tp_proc;
- }
- ex = makeexpr(EK_SPCALL, 1);
- ex->val.type = tp_void;
- ex->args[0] = copyexpr(ex2);
- if (type->escale != 0)
- ex->args[0] = makeexpr_cast(makeexpr_dotq(ex2, "proc", tp_anyptr),
- makepointertype(type->basetype));
- mp = type->basetype->fbase;
- if (mp) {
- if (wneedtok(TOK_COMMA))
- ex = p_funcarglist(ex, mp, 0, 0);
- }
- skipcloseparen();
- if (type->escale != 1 || hasstaticlinks == 2) {
- freeexpr(ex2);
- return makestmt_call(ex);
- }
- ex2 = makeexpr_dotq(ex2, "link", tp_anyptr),
- ex3 = copyexpr(ex);
- insertarg(&ex3, ex3->nargs, copyexpr(ex2));
- tp = maketype(TK_FUNCTION);
- tp->basetype = type->basetype->basetype;
- tp->fbase = type->basetype->fbase;
- tp->issigned = 1;
- ex3->args[0]->val.type = makepointertype(tp);
- return makestmt_if(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
- makestmt_call(ex3),
- makestmt_call(ex));
- }
- Static Expr *func_chr()
- {
- Expr *ex;
- ex = p_expr(tp_integer);
- if ((exprlongness(ex) < 0 || ex->kind == EK_CAST) && ex->kind != EK_ACTCAST)
- ex->val.type = tp_char;
- else
- ex = makeexpr_cast(ex, tp_char);
- return ex;
- }
- Static Stmt *proc_close()
- {
- Stmt *sp;
- Expr *fex, *ex;
- char *opt;
- if (!skipopenparen())
- return NULL;
- fex = p_expr(tp_text);
- sp = makestmt_if(makeexpr_rel(EK_NE, copyexpr(fex), makeexpr_nil()),
- makestmt_call(makeexpr_bicall_1("fclose", tp_void,
- copyexpr(fex))),
- (FCheck(checkfileisopen))
- ? makestmt_call(
- makeexpr_bicall_1(name_ESCIO,
- tp_integer,
- makeexpr_name(filenotopenname,
- tp_int)))
- : NULL);
- if (curtok == TOK_COMMA) {
- gettok();
- opt = "";
- if (curtok == TOK_IDENT &&
- (!strcicmp(curtokbuf, "LOCK") ||
- !strcicmp(curtokbuf, "PURGE") ||
- !strcicmp(curtokbuf, "NORMAL") ||
- !strcicmp(curtokbuf, "CRUNCH"))) {
- opt = stralloc(curtokbuf);
- gettok();
- } else {
- ex = p_expr(tp_str255);
- if (ex->kind == EK_CONST && ex->val.type->kind == TK_STRING)
- opt = ex->val.s;
- }
- if (!strcicmp(opt, "PURGE")) {
- note("File is being closed with PURGE option [186]");
- }
- }
- sp = makestmt_seq(sp, makestmt_assign(fex, makeexpr_nil()));
- skipcloseparen();
- return sp;
- }
- Static Expr *func_concat()
- {
- Expr *ex;
- if (!skipopenparen())
- return makeexpr_string("oops");
- ex = p_expr(tp_str255);
- while (curtok == TOK_COMMA) {
- gettok();
- ex = makeexpr_concat(ex, p_expr(tp_str255), 0);
- }
- skipcloseparen();
- return ex;
- }
- Static Expr *func_copy(ex)
- Expr *ex;
- {
- if (isliteralconst(ex->args[3], NULL) == 2 &&
- ex->args[3]->val.i >= stringceiling) {
- return makeexpr_bicall_3("sprintf", ex->val.type,
- ex->args[0],
- makeexpr_string("%s"),
- bumpstring(ex->args[1],
- makeexpr_unlongcast(ex->args[2]), 1));
- }
- if (checkconst(ex->args[2], 1)) {
- return makeexpr_addr(makeexpr_substring(ex->args[0], ex->args[1],
- ex->args[2], ex->args[3]));
- }
- return makeexpr_bicall_4(strsubname, ex->val.type,
- ex->args[0],
- ex->args[1],
- makeexpr_arglong(ex->args[2], 0),
- makeexpr_arglong(ex->args[3], 0));
- }
- Static Expr *func_cos(ex)
- Expr *ex;
- {
- return makeexpr_bicall_1("cos", tp_longreal, grabarg(ex, 0));
- }
- Static Expr *func_cosh(ex)
- Expr *ex;
- {
- return makeexpr_bicall_1("cosh", tp_longreal, grabarg(ex, 0));
- }
- Static Stmt *proc_cycle()
- {
- return makestmt(SK_CONTINUE);
- }
- Static Stmt *proc_dec()
- {
- Expr *vex, *ex;
- if (!skipopenparen())
- return NULL;
- vex = p_expr(NULL);
- if (curtok == TOK_COMMA) {
- gettok();
- ex = p_expr(tp_integer);
- } else
- ex = makeexpr_long(1);
- skipcloseparen();
- return makestmt_assign(vex, makeexpr_minus(copyexpr(vex), ex));
- }
- Static Expr *func_dec()
- {
- return handle_vax_hex(NULL, "d", 0);
- }
- Static Stmt *proc_delete(ex)
- Expr *ex;
- {
- if (ex->nargs == 1) /* Kludge for Oregon Software Pascal's delete(f) */
- return makestmt_call(makeexpr_bicall_1(strdeletename, tp_void, ex->args[0]));
- return makestmt_call(makeexpr_bicall_3(strdeletename, tp_void,
- ex->args[0],
- makeexpr_arglong(ex->args[1], 0),
- makeexpr_arglong(ex->args[2], 0)));
- }
- void parse_special_variant(tp, buf)
- Type *tp;
- char *buf;
- {
- char *cp;
- Expr *ex;
- if (!tp)
- intwarning("parse_special_variant", "tp == NULL");
- if (!tp || tp->meaning == NULL) {
- *buf = 0;
- if (curtok == TOK_COMMA) {
- skiptotoken(TOK_RPAR);
- }
- return;
- }
- strcpy(buf, tp->meaning->name);
- while (curtok == TOK_COMMA) {
- gettok();
- cp = buf + strlen(buf);
- *cp++ = '.';
- if (curtok == TOK_MINUS) {
- *cp++ = '-';
- gettok();
- }
- if (curtok == TOK_INTLIT ||
- curtok == TOK_HEXLIT ||
- curtok == TOK_OCTLIT) {
- sprintf(cp, "%ld", curtokint);
- gettok();
- } else if (curtok == TOK_HAT || curtok == TOK_STRLIT) {
- ex = makeexpr_charcast(accumulate_strlit());
- if (ex->kind == EK_CONST) {
- if (ex->val.i <= 32 || ex->val.i > 126 ||
- ex->val.i == ''' || ex->val.i == '\' ||
- ex->val.i == '=' || ex->val.i == '}')
- sprintf(cp, "%ld", ex->val.i);
- else
- strcpy(cp, makeCchar(ex->val.i));
- } else {
- *buf = 0;
- *cp = 0;
- }
- freeexpr(ex);
- } else {
- if (!wexpecttok(TOK_IDENT)) {
- skiptotoken(TOK_RPAR);
- return;
- }
- if (curtokmeaning)
- strcpy(cp, curtokmeaning->name);
- else
- strcpy(cp, curtokbuf);
- gettok();
- }
- }
- }
- char *find_special_variant(buf, spname, splist, need)
- char *buf, *spname;
- Strlist *splist;
- int need;
- {
- Strlist *best = NULL;
- int len, bestlen = -1;
- char *cp, *cp2;
- if (!*buf)
- return NULL;
- while (splist) {
- cp = splist->s;
- cp2 = buf;
- while (*cp && toupper(*cp) == toupper(*cp2))
- cp++, cp2++;
- len = cp2 - buf;
- if (!*cp && (!*cp2 || *cp2 == '.') && len > bestlen) {
- best = splist;
- bestlen = len;
- }
- splist = splist->next;
- }
- if (bestlen != strlen(buf) && my_strchr(buf, '.')) {
- if ((need & 1) || bestlen >= 0) {
- if (need & 2)
- return NULL;
- if (spname)
- note(format_ss("No %s form known for %s [187]",
- spname, strupper(buf)));
- }
- }
- if (bestlen >= 0)
- return (char *)best->value;
- else
- return NULL;
- }
- Static char *choose_free_func(ex)
- Expr *ex;
- {
- if (!*freename) {
- if (!*freervaluename)
- return "free";
- else
- return freervaluename;
- }
- if (!*freervaluename)
- return freervaluename;
- if (expr_is_lvalue(ex))
- return freename;
- else
- return freervaluename;
- }
- Static Stmt *proc_dispose()
- {
- Expr *ex;
- Type *type;
- char *name, vbuf[1000];
- if (!skipopenparen())
- return NULL;
- ex = p_expr(tp_anyptr);
- type = ex->val.type->basetype;
- parse_special_variant(type, vbuf);
- skipcloseparen();
- name = find_special_variant(vbuf, "SpecialFree", specialfrees, 0);
- if (!name)
- name = choose_free_func(ex);
- return makestmt_call(makeexpr_bicall_1(name, tp_void, ex));
- }
- Static Expr *func_exp(ex)
- Expr *ex;
- {
- return makeexpr_bicall_1("exp", tp_longreal, grabarg(ex, 0));
- }
- Static Expr *func_expo(ex)
- Expr *ex;
- {
- Meaning *tvar;
- tvar = makestmttempvar(tp_int, name_TEMP);
- return makeexpr_comma(makeexpr_bicall_2("frexp", tp_longreal,
- grabarg(ex, 0),
- makeexpr_addr(makeexpr_var(tvar))),
- makeexpr_var(tvar));
- }
- int is_std_file(ex)
- Expr *ex;
- {
- return isvar(ex, mp_input) || isvar(ex, mp_output) ||
- isvar(ex, mp_stderr);
- }
- Static Expr *iofunc(ex, code)
- Expr *ex;
- int code;
- {
- Expr *ex2 = NULL, *ex3 = NULL;
- Meaning *tvar = NULL;
- if (FCheck(checkfileisopen) && !is_std_file(ex)) {
- if (exprspeed(ex) < 5 && nosideeffects(ex, 0)) {
- ex2 = copyexpr(ex);
- } else {
- ex3 = ex;
- tvar = makestmttempvar(ex->val.type, name_TEMP);
- ex2 = makeexpr_var(tvar);
- ex = makeexpr_var(tvar);
- }
- }
- switch (code) {
- case 0: /* eof */
- if (*eofname)
- ex = makeexpr_bicall_1(eofname, tp_boolean, ex);
- else
- ex = makeexpr_rel(EK_NE, makeexpr_bicall_1("feof", tp_int, ex),
- makeexpr_long(0));
- break;
- case 1: /* eoln */
- ex = makeexpr_bicall_1(eolnname, tp_boolean, ex);
- break;
- case 2: /* position or filepos */
- ex = makeexpr_bicall_1(fileposname, tp_integer, ex);
- break;
- case 3: /* maxpos or filesize */
- ex = makeexpr_bicall_1(maxposname, tp_integer, ex);
- break;
- }
- if (ex2) {
- ex = makeexpr_bicall_4("~CHKIO",
- (code == 0 || code == 1) ? tp_boolean : tp_integer,
- makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
- makeexpr_name("FileNotOpen", tp_int),
- ex, makeexpr_long(0));
- }
- if (ex3)
- ex = makeexpr_comma(makeexpr_assign(makeexpr_var(tvar), ex3), ex);
- return ex;
- }
- Static Expr *func_eof()
- {
- Expr *ex;
- if (curtok == TOK_LPAR)
- ex = p_parexpr(tp_text);
- else
- ex = makeexpr_var(mp_input);
- return iofunc(ex, 0);
- }
- Static Expr *func_eoln()
- {
- Expr *ex;
- if (curtok == TOK_LPAR)
- ex = p_parexpr(tp_text);
- else
- ex = makeexpr_var(mp_input);
- return iofunc(ex, 1);
- }
- Static Stmt *proc_escape()
- {
- Expr *ex;
- if (curtok == TOK_LPAR)
- ex = p_parexpr(tp_integer);
- else
- ex = makeexpr_long(0);
- return makestmt_call(makeexpr_bicall_1(name_ESCAPE, tp_int,
- makeexpr_arglong(ex, 0)));
- }
- Static Stmt *proc_excl()
- {
- Expr *vex, *ex;
- if (!skipopenparen())
- return NULL;
- vex = p_expr(NULL);
- if (!skipcomma())
- return NULL;
- ex = p_expr(vex->val.type->indextype);
- skipcloseparen();
- if (vex->val.type->kind == TK_SMALLSET)
- return makestmt_assign(vex, makeexpr_bin(EK_BAND, vex->val.type,
- copyexpr(vex),
- makeexpr_un(EK_BNOT, vex->val.type,
- makeexpr_bin(EK_LSH, vex->val.type,
- makeexpr_longcast(makeexpr_long(1), 1),
- ex))));
- else
- return makestmt_call(makeexpr_bicall_2(setremname, tp_void, vex,
- makeexpr_arglong(enum_to_int(ex), 0)));
- }
- Stmt *proc_exit()
- {
- Stmt *sp;
- if (modula2) {
- return makestmt(SK_BREAK);
- }
- if (curtok == TOK_LPAR) {
- gettok();
- if (curtok == TOK_PROGRAM ||
- (curtok == TOK_IDENT && curtokmeaning->kind == MK_MODULE)) {
- gettok();
- skipcloseparen();
- return makestmt_call(makeexpr_bicall_1("exit", tp_void,
- makeexpr_long(0)));
- }
- if (curtok != TOK_IDENT || !curtokmeaning || curtokmeaning != curctx)
- note("Attempting to EXIT beyond this function [188]");
- gettok();
- skipcloseparen();
- }
- sp = makestmt(SK_RETURN);
- if (curctx->kind == MK_FUNCTION && curctx->isfunction) {
- sp->exp1 = makeexpr_var(curctx->cbase);
- curctx->cbase->refcount++;
- }
- return sp;
- }
- Static Expr *file_iofunc(code, base)
- int code;
- long base;
- {
- Expr *ex;
- Type *basetype;
- if (curtok == TOK_LPAR)
- ex = p_parexpr(tp_text);
- else
- ex = makeexpr_var(mp_input);
- if (!ex->val.type || !ex->val.type->basetype ||
- !ex->val.type->basetype->basetype)
- basetype = tp_char;
- else
- basetype = ex->val.type->basetype->basetype;
- return makeexpr_plus(makeexpr_div(iofunc(ex, code),
- makeexpr_sizeof(makeexpr_type(basetype), 0)),
- makeexpr_long(base));
- }
- Static Expr *func_fcall()
- {
- Expr *ex, *ex2, *ex3;
- Type *type, *tp;
- Meaning *mp, *tvar = NULL;
- int firstarg = 0;
- if (!skipopenparen())
- return NULL;
- ex2 = p_expr(tp_proc);
- type = ex2->val.type;
- if (type->kind != TK_PROCPTR && type->kind != TK_CPROCPTR) {
- warning("FCALL requires a function variable [209]");
- type = tp_proc;
- }
- ex = makeexpr(EK_SPCALL, 1);
- ex->val.type = type->basetype->basetype;
- ex->args[0] = copyexpr(ex2);
- if (type->escale != 0)
- ex->args[0] = makeexpr_cast(makeexpr_dotq(ex2, "proc", tp_anyptr),
- makepointertype(type->basetype));
- mp = type->basetype->fbase;
- if (mp && mp->isreturn) { /* pointer to buffer for return value */
- tvar = makestmttempvar(ex->val.type->basetype,
- (ex->val.type->basetype->kind == TK_STRING) ? name_STRING : name_TEMP);
- insertarg(&ex, 1, makeexpr_addr(makeexpr_var(tvar)));
- mp = mp->xnext;
- firstarg++;
- }
- if (mp) {
- if (wneedtok(TOK_COMMA))
- ex = p_funcarglist(ex, mp, 0, 0);
- }
- if (tvar)
- ex = makeexpr_hat(ex, 0); /* returns pointer to structured result */
- skipcloseparen();
- if (type->escale != 1 || hasstaticlinks == 2) {
- freeexpr(ex2);
- return ex;
- }
- ex2 = makeexpr_dotq(ex2, "link", tp_anyptr),
- ex3 = copyexpr(ex);
- insertarg(&ex3, ex3->nargs, copyexpr(ex2));
- tp = maketype(TK_FUNCTION);
- tp->basetype = type->basetype->basetype;
- tp->fbase = type->basetype->fbase;
- tp->issigned = 1;
- ex3->args[0]->val.type = makepointertype(tp);
- return makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
- ex3, ex);
- }
- Static Expr *func_filepos()
- {
- return file_iofunc(2, seek_base);
- }
- Static Expr *func_filesize()
- {
- return file_iofunc(3, 1L);
- }
- Static Stmt *proc_fillchar()
- {
- Expr *vex, *ex, *cex;
- if (!skipopenparen())
- return NULL;
- vex = gentle_cast(makeexpr_addr(p_expr(NULL)), tp_anyptr);
- if (!skipcomma())
- return NULL;
- ex = convert_size(argbasetype(vex), p_expr(tp_integer), "FILLCHAR");
- if (!skipcomma())
- return NULL;
- cex = makeexpr_charcast(p_expr(tp_integer));
- skipcloseparen();
- return makestmt_call(makeexpr_bicall_3("memset", tp_void,
- vex,
- makeexpr_arglong(cex, 0),
- makeexpr_arglong(ex, (size_t_long != 0))));
- }
- Static Expr *func_sngl()
- {
- Expr *ex;
- ex = p_parexpr(tp_real);
- return makeexpr_cast(ex, tp_real);
- }
- Static Expr *func_float()
- {
- Expr *ex;
- ex = p_parexpr(tp_longreal);
- return makeexpr_cast(ex, tp_longreal);
- }
- Static Stmt *proc_flush()
- {
- Expr *ex;
- Stmt *sp;
- ex = p_parexpr(tp_text);
- sp = makestmt_call(makeexpr_bicall_1("fflush", tp_void, ex));
- if (iocheck_flag)
- sp = makestmt_seq(sp, makestmt_assign(makeexpr_var(mp_ioresult),
- makeexpr_long(0)));
- return sp;
- }
- Static Expr *func_frac(ex)
- Expr *ex;
- {
- Meaning *tvar;
- tvar = makestmttempvar(tp_longreal, name_DUMMY);
- return makeexpr_bicall_2("modf", tp_longreal,
- grabarg(ex, 0),
- makeexpr_addr(makeexpr_var(tvar)));
- }
- Static Stmt *proc_freemem(ex)
- Expr *ex;
- {
- Stmt *sp;
- Expr *vex;
- vex = makeexpr_hat(eatcasts(ex->args[0]), 0);
- sp = makestmt_call(makeexpr_bicall_1(choose_free_func(vex),
- tp_void, copyexpr(vex)));
- if (alloczeronil) {
- sp = makestmt_if(makeexpr_rel(EK_NE, vex, makeexpr_nil()),
- sp, NULL);
- } else
- freeexpr(vex);
- return sp;
- }
- Static Stmt *proc_get()
- {
- Expr *ex;
- Type *type;
- if (curtok == TOK_LPAR)
- ex = p_parexpr(tp_text);
- else
- ex = makeexpr_var(mp_input);
- requirefilebuffer(ex);
- type = ex->val.type;
- if (isfiletype(type) && *chargetname &&
- type->basetype->basetype->kind == TK_CHAR)
- return makestmt_call(makeexpr_bicall_1(chargetname, tp_void, ex));
- else if (isfiletype(type) && *arraygetname &&
- type->basetype->basetype->kind == TK_ARRAY)
- return makestmt_call(makeexpr_bicall_2(arraygetname, tp_void, ex,
- makeexpr_type(type->basetype->basetype)));
- else