parent
96079b210e
commit
9670e8b4a1
@ -249,9 +249,9 @@ static int print_string(char* dest, size_t space,
|
||||
/*}}}*/
|
||||
|
||||
/* printtok -- print a single token, passed by address, although not changed */ /*{{{*/
|
||||
size_t printtok(char* dest, size_t size, size_t field_width,
|
||||
StringFormat sf, FloatFormat ff,
|
||||
int digits, ErrorFormat ef, const Token *tok)
|
||||
size_t ptokatprec(char* dest, size_t size, size_t field_width, StringFormat sf,
|
||||
FloatFormat ff, int digits, ErrorFormat ef, const Token *tok,
|
||||
FunctionPrecedence atprec)
|
||||
{
|
||||
if (debug_level > 2) {
|
||||
printf("..Entering printtok; bufsize %d, field_width %d, qs %d, ff %s,"
|
||||
@ -381,17 +381,76 @@ size_t printtok(char* dest, size_t size, size_t field_width,
|
||||
/* FUNCALL */ /*{{{*/
|
||||
case FUNCALL:
|
||||
{
|
||||
cur += print_fident(dest+cur, size-cur-1, tok->u.funcall.fident);
|
||||
if (tok->u.funcall.argc >= 0 && cur + 2 < size) /* -1 args is bare func */
|
||||
FunctionIdentifier fid = tok->u.funcall.fident;
|
||||
if (tok->u.funcall.argc <= 0)
|
||||
{
|
||||
dest[cur++] = '\(';
|
||||
cur += print_fident(dest+cur, size-cur-1, fid);
|
||||
if (tok->u.funcall.argc == 0)
|
||||
{
|
||||
if (cur < size - 2) { dest[cur++] = '('; dest[cur++] = ')'; }
|
||||
else cur += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
FunctionPrecedence fp = tfunc[fid].precedence;
|
||||
switch (fp)
|
||||
{
|
||||
case PREFIX_FUNC: {
|
||||
cur += print_fident(dest+cur, size-cur-1, fid);
|
||||
if (cur < size) dest[cur++] = '(';
|
||||
for (size_t ai = 0; ai < tok->u.funcall.argc && cur < size-1; ++ai)
|
||||
{
|
||||
if (ai > 0 && cur < size) dest[cur++] = ',';
|
||||
cur += printtok(dest+cur, size-cur-1, field_width-cur, sf, ff,
|
||||
digits, ef, tok->u.funcall.argv + ai);
|
||||
/* The commas eliminate the need for precedence worries in arguments*/
|
||||
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
|
||||
digits, ef, tok->u.funcall.argv + ai,
|
||||
NO_PRECEDENCE);
|
||||
}
|
||||
if (cur < size) dest[cur++] = ')';
|
||||
break;
|
||||
}
|
||||
case PREFIX_NEG: {
|
||||
assert(tok->u.funcall.argc == 1);
|
||||
assert(tfunc[fid].display_symbol != NULL);
|
||||
if (fp < atprec && cur < size) dest[cur++] = '(';
|
||||
if (cur < size) {
|
||||
strncpy(dest+cur, tfunc[fid].display_symbol, size-cur-1);
|
||||
cur += strlen(tfunc[fid].display_symbol);
|
||||
}
|
||||
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
|
||||
digits, ef, tok->u.funcall.argv, fp);
|
||||
if (fp < atprec && cur < size) dest[cur++] = ')';
|
||||
break;
|
||||
}
|
||||
default: /* infix argument */
|
||||
assert(tok->u.funcall.argc > 1);
|
||||
if (fp < atprec && cur < size) dest[cur++] = '(';
|
||||
for (size_t ai = 0; ai < tok->u.funcall.argc && cur < size-1; ++ ai)
|
||||
{
|
||||
bool parenarg = false;
|
||||
if (ai > 0) {
|
||||
if (fp < INFIX_MUL && cur < size) dest[cur++] = ' ';
|
||||
const char *use = tfunc[fid].display_symbol;
|
||||
if (use == NULL) use = tfunc[fid].name;
|
||||
strncpy(dest+cur, use, size-cur-1);
|
||||
cur += strlen(use);
|
||||
if (fp < INFIX_MUL && cur < size) dest[cur++] = ' ';
|
||||
} else if (fp > PREFIX_NEG) {
|
||||
char powbuf[4096];
|
||||
size_t arglen = ptokatprec(powbuf, sizeof(powbuf), 0, sf, ff,
|
||||
digits, ef, tok->u.funcall.argv, fp);
|
||||
assert(arglen < sizeof(powbuf)-1);
|
||||
if (powbuf[0] == '-') {
|
||||
parenarg = true;
|
||||
if (cur < size) dest[cur++] = '(';
|
||||
}
|
||||
}
|
||||
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
|
||||
digits, ef, tok->u.funcall.argv + ai, fp);
|
||||
if (parenarg && cur < size) dest[cur++] = ')';
|
||||
}
|
||||
if (fp < atprec && cur < size) dest[cur++] = ')';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -439,6 +498,16 @@ size_t printtok(char* dest, size_t size, size_t field_width,
|
||||
}
|
||||
/*}}}*/
|
||||
|
||||
/* printtok -- print a single token, passed by address, although not changed */ /*{{{*/
|
||||
size_t printtok(char* dest, size_t size, size_t field_width,
|
||||
StringFormat sf, FloatFormat ff,
|
||||
int digits, ErrorFormat ef, const Token *tok)
|
||||
{
|
||||
return ptokatprec(dest, size, field_width, sf, ff, digits, ef, tok,
|
||||
NO_PRECEDENCE);
|
||||
}
|
||||
/*}}}*/
|
||||
|
||||
/* print -- print token sequence */ /*{{{*/
|
||||
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff,
|
||||
int digits, Token **n)
|
||||
|
@ -390,7 +390,7 @@ static Token at_func(int argc, const Token argv[], LocConvention lcon)
|
||||
strcat(result.u.err, location.u.err);
|
||||
/* don't free the location if it is the same as an argument, because
|
||||
those get freed later: */
|
||||
for (size_t i = 0; i < argc; ++i)
|
||||
for (int i = 0; i < argc; ++i)
|
||||
if (argv[i].type == EEK & argv[i].u.err == location.u.err) return result;
|
||||
tfree(&location);
|
||||
return result;
|
||||
|
@ -36,8 +36,8 @@ typedef struct Token_struc Token;
|
||||
|
||||
typedef enum /* In increasing order of precedence */
|
||||
{
|
||||
INFIX_CONC, INFIX_REL, INFIX_PLUS, INFIX_MUL, PREFIX_NEG,
|
||||
INFIX_POW, PREFIX_FUNC
|
||||
NO_PRECEDENCE, INFIX_CONC, INFIX_REL, INFIX_PLUS, INFIX_MUL,
|
||||
PREFIX_NEG, INFIX_POW, PREFIX_FUNC
|
||||
} FunctionPrecedence;
|
||||
|
||||
typedef enum { FUNCT, MACRO } EvaluationStrategy;
|
||||
|
Loading…
Reference in New Issue
Block a user