home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
379a.lha
/
p2c1_13a
/
src
/
src.zoo
/
funcs1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-11
|
26KB
|
960 lines
/* "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_FUNCS1_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;
}
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));
}
}
}
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;
}
Expr *func_iaddress()
{
return makeexpr_cast(func_addr(), tp_integer);
}
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));
}
}
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);
}
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;
}
Stmt *proc_append()
{
return handleopen(3);
}
Expr *func_arccos(ex)
Expr *ex;
{
return makeexpr_bicall_1("acos", tp_longreal, grabarg(ex, 0));
}
Expr *func_arcsin(ex)
Expr *ex;
{
return makeexpr_bicall_1("asin", tp_longreal, grabarg(ex, 0));
}
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);
}
Expr *func_arctanh(ex)
Expr *ex;
{
return makeexpr_bicall_1("atanh", tp_longreal, grabarg(ex, 0));
}
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)));
}
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;
}
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;
}
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;
}
Expr *func_bin()
{
note("Using %b for binary printf format [185]");
return handle_vax_hex(NULL, "b", 1);
}
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));
}
Expr *func_bitsize()
{
return handle_bitsize(0);
}
Expr *func_bitnext()
{
return handle_bitsize(1);
}
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);
}
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);
}
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);
}