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 */ /*{{{*/
|
/* printtok -- print a single token, passed by address, although not changed */ /*{{{*/
|
||||||
size_t printtok(char* dest, size_t size, size_t field_width,
|
size_t ptokatprec(char* dest, size_t size, size_t field_width, StringFormat sf,
|
||||||
StringFormat sf, FloatFormat ff,
|
FloatFormat ff, int digits, ErrorFormat ef, const Token *tok,
|
||||||
int digits, ErrorFormat ef, const Token *tok)
|
FunctionPrecedence atprec)
|
||||||
{
|
{
|
||||||
if (debug_level > 2) {
|
if (debug_level > 2) {
|
||||||
printf("..Entering printtok; bufsize %d, field_width %d, qs %d, ff %s,"
|
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 */ /*{{{*/
|
/* FUNCALL */ /*{{{*/
|
||||||
case FUNCALL:
|
case FUNCALL:
|
||||||
{
|
{
|
||||||
cur += print_fident(dest+cur, size-cur-1, tok->u.funcall.fident);
|
FunctionIdentifier fid = tok->u.funcall.fident;
|
||||||
if (tok->u.funcall.argc >= 0 && cur + 2 < size) /* -1 args is bare func */
|
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)
|
for (size_t ai = 0; ai < tok->u.funcall.argc && cur < size-1; ++ai)
|
||||||
{
|
{
|
||||||
if (ai > 0 && cur < size) dest[cur++] = ',';
|
if (ai > 0 && cur < size) dest[cur++] = ',';
|
||||||
cur += printtok(dest+cur, size-cur-1, field_width-cur, sf, ff,
|
/* The commas eliminate the need for precedence worries in arguments*/
|
||||||
digits, ef, tok->u.funcall.argv + ai);
|
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++] = ')';
|
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;
|
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 */ /*{{{*/
|
/* print -- print token sequence */ /*{{{*/
|
||||||
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff,
|
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff,
|
||||||
int digits, Token **n)
|
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);
|
strcat(result.u.err, location.u.err);
|
||||||
/* don't free the location if it is the same as an argument, because
|
/* don't free the location if it is the same as an argument, because
|
||||||
those get freed later: */
|
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;
|
if (argv[i].type == EEK & argv[i].u.err == location.u.err) return result;
|
||||||
tfree(&location);
|
tfree(&location);
|
||||||
return result;
|
return result;
|
||||||
|
@ -36,8 +36,8 @@ typedef struct Token_struc Token;
|
|||||||
|
|
||||||
typedef enum /* In increasing order of precedence */
|
typedef enum /* In increasing order of precedence */
|
||||||
{
|
{
|
||||||
INFIX_CONC, INFIX_REL, INFIX_PLUS, INFIX_MUL, PREFIX_NEG,
|
NO_PRECEDENCE, INFIX_CONC, INFIX_REL, INFIX_PLUS, INFIX_MUL,
|
||||||
INFIX_POW, PREFIX_FUNC
|
PREFIX_NEG, INFIX_POW, PREFIX_FUNC
|
||||||
} FunctionPrecedence;
|
} FunctionPrecedence;
|
||||||
|
|
||||||
typedef enum { FUNCT, MACRO } EvaluationStrategy;
|
typedef enum { FUNCT, MACRO } EvaluationStrategy;
|
||||||
|
Loading…
Reference in New Issue
Block a user