mirror of
git://git.suckless.org/sbase
synced 2026-01-26 13:43:17 +00:00
bc: Add support for long names
As dc supports extended identifiers and we already had the option -s in bc that modifies the standard behaviour we can extend bc in the -s mode to support longer names. The lower case restriction is maintained just for simplicity but it is possible to extend bc to support full utf8 identifers.
This commit is contained in:
parent
759ef4f504
commit
c5bfe949dc
13
bc.1
13
bc.1
@ -41,10 +41,19 @@ Enable yacc parser debugging output.
|
||||
Load the mathematical library
|
||||
that is loaded before any file from the command line.
|
||||
.It Fl s
|
||||
Suppresses the automatic printing of expression results.
|
||||
In this mode, only explicit
|
||||
Enable the extended mode.
|
||||
In this mode,
|
||||
the automatic printing of expression results is suppressed,
|
||||
and only explicit
|
||||
.Ic print
|
||||
statements produce output.
|
||||
Names of variables and functions can be longer than 1 character,
|
||||
but still constrained to lower case latin characters.
|
||||
The output of
|
||||
.Ar bc
|
||||
in this mode is suitable only for the suckless
|
||||
.Ar dc
|
||||
version.
|
||||
.El
|
||||
.Sh LANGUAGE
|
||||
.Ss Comments
|
||||
|
||||
69
bc.y
69
bc.y
@ -26,6 +26,7 @@ typedef struct macro Macro;
|
||||
struct macro {
|
||||
int op;
|
||||
int id;
|
||||
char *name;
|
||||
int flowid;
|
||||
int nested;
|
||||
};
|
||||
@ -348,6 +349,7 @@ macro(int op)
|
||||
d = ¯os[nested];
|
||||
d->op = op;
|
||||
d->nested = nested++;
|
||||
d->name = NULL;
|
||||
|
||||
switch (op) {
|
||||
case HOME:
|
||||
@ -359,6 +361,7 @@ macro(int op)
|
||||
unwind = estrdup("");
|
||||
inhome = 0;
|
||||
d->id = funid(yytext);
|
||||
d->name = estrdup(yytext);
|
||||
d->flowid = macros[0].flowid;
|
||||
break;
|
||||
default:
|
||||
@ -417,17 +420,26 @@ funcode(Macro *d, char *params, char *vars, char *body)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = code("[%s%s%s%s]s%c",
|
||||
vars, params,
|
||||
body,
|
||||
retcode(code(" 0")),
|
||||
d->id);
|
||||
if (strlen(d->name) > 1) {
|
||||
s = code("[%s%s%s%s]s\"()%s\"",
|
||||
vars, params,
|
||||
body,
|
||||
retcode(code(" 0")),
|
||||
d->name);
|
||||
} else {
|
||||
s = code(sflag ? "[%s%s%s%s]s<%d>" : "[%s%s%s%s]s%c",
|
||||
vars, params,
|
||||
body,
|
||||
retcode(code(" 0")),
|
||||
d->id);
|
||||
free(d->name);
|
||||
}
|
||||
|
||||
free(unwind);
|
||||
unwind = NULL;
|
||||
nested--;
|
||||
inhome = 0;
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -448,14 +460,17 @@ forcode(Macro *d, char *init, char *cmp, char *inc, char *body)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = code("[%s%ss.%s%c]s%c",
|
||||
s = code(sflag ? "[%s%ss.%s<%d>]s<%d>" : "[%s%ss.%s%c]s%c",
|
||||
body,
|
||||
inc,
|
||||
estrdup(cmp),
|
||||
d->id, d->id);
|
||||
writeout(s);
|
||||
|
||||
s = code("%ss.%s%c ", init, cmp, d->id);
|
||||
s = code(sflag ? "%ss.%s<%d> " : "%ss.%s%c ",
|
||||
init,
|
||||
cmp,
|
||||
d->id);
|
||||
nested--;
|
||||
|
||||
return s;
|
||||
@ -466,13 +481,14 @@ whilecode(Macro *d, char *cmp, char *body)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = code("[%s%s%c]s%c",
|
||||
s = code(sflag ? "[%s%s<%d>]s<%d>" : "[%s%s%c]s%c",
|
||||
body,
|
||||
estrdup(cmp),
|
||||
d->id, d->id);
|
||||
writeout(s);
|
||||
|
||||
s = code("%s%c ", cmp, d->id);
|
||||
s = code(sflag ? "%s<%d> " : "%s%c ",
|
||||
cmp, d->id);
|
||||
nested--;
|
||||
|
||||
return s;
|
||||
@ -483,10 +499,12 @@ ifcode(Macro *d, char *cmp, char *body)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = code("[%s]s%c", body, d->id);
|
||||
s = code(sflag ? "[%s]s<%d>" : "[%s]s%c",
|
||||
body, d->id);
|
||||
writeout(s);
|
||||
|
||||
s = code("%s%c ", cmp, d->id);
|
||||
s = code(sflag ? "%s<%d> " : "%s%c ",
|
||||
cmp, d->id);
|
||||
nested--;
|
||||
|
||||
return s;
|
||||
@ -505,19 +523,25 @@ retcode(char *expr)
|
||||
static char *
|
||||
ary(char *s)
|
||||
{
|
||||
return code("%c", toupper(s[0]));
|
||||
if (strlen(s) == 1)
|
||||
return code("%c", toupper(s[0]));
|
||||
return code("\"[]%s\"", estrdup(s));
|
||||
}
|
||||
|
||||
static char *
|
||||
ftn(char *s)
|
||||
{
|
||||
return code("%c", funid(s));
|
||||
if (strlen(s) == 1)
|
||||
return code(sflag ? "<%d>" : "%c", funid(s));
|
||||
return code("\"()%s\"", estrdup(s));
|
||||
}
|
||||
|
||||
static char *
|
||||
var(char *s)
|
||||
{
|
||||
return code(s);
|
||||
if (strlen(s) == 1)
|
||||
return code(s);
|
||||
return code("\"%s\"", estrdup(s));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -531,7 +555,7 @@ skipspaces(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
while (isspace(ch = getc(filep))) {
|
||||
while (isascii(ch = getc(filep)) && isspace(ch)) {
|
||||
if (ch == '\n') {
|
||||
lineno++;
|
||||
break;
|
||||
@ -569,7 +593,7 @@ iden(int ch)
|
||||
ungetc(ch, filep);
|
||||
for (bp = yytext; bp < &yytext[BUFSIZ]; ++bp) {
|
||||
ch = getc(filep);
|
||||
if (!islower(ch))
|
||||
if (!isascii || !islower(ch))
|
||||
break;
|
||||
*bp = ch;
|
||||
}
|
||||
@ -586,11 +610,13 @@ iden(int ch)
|
||||
|
||||
for (p = keywords; p->str && strcmp(p->str, yytext); ++p)
|
||||
;
|
||||
if (p->str)
|
||||
return p->token;
|
||||
|
||||
if (!p->str)
|
||||
if (!sflag)
|
||||
yyerror("invalid keyword");
|
||||
|
||||
return p->token;
|
||||
strcpy(yylval.id, yytext);
|
||||
return ID;
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -785,6 +811,7 @@ static void
|
||||
spawn(void)
|
||||
{
|
||||
int fds[2];
|
||||
char *par = sflag ? "-i" : NULL;
|
||||
char errmsg[] = "bc:error execing dc\n";
|
||||
|
||||
if (pipe(fds) < 0)
|
||||
@ -804,7 +831,7 @@ spawn(void)
|
||||
dup(fds[0]);
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
execlp(dcprog, "dc", (char *) NULL);
|
||||
execlp(dcprog, "dc", par, (char *) NULL);
|
||||
|
||||
/* it shouldn't happen */
|
||||
write(3, errmsg, sizeof(errmsg)-1);
|
||||
|
||||
26
tests/0050-bc.sh
Executable file
26
tests/0050-bc.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
tmp=$$.tmp
|
||||
|
||||
trap 'rm -f $tmp' EXIT
|
||||
trap 'exit $?' HUP INT TERM
|
||||
|
||||
cat <<'EOF' > $tmp
|
||||
par=1
|
||||
inc=4
|
||||
EOF
|
||||
|
||||
$EXEC ../bc -sp ../dc <<'EOF' | diff -u - $tmp
|
||||
define alpha(par, inc) {
|
||||
auto cnt
|
||||
|
||||
par = par + 1
|
||||
cnt = par + inc
|
||||
return (cnt)
|
||||
}
|
||||
|
||||
par = 1
|
||||
inc = alpha(par, 2)
|
||||
print "par=",par
|
||||
print "inc=",inc
|
||||
EOF
|
||||
Loading…
x
Reference in New Issue
Block a user