pc: add $ operator

This commit is contained in:
aiju 2018-05-04 11:07:39 +01:00
parent fa028a9352
commit 454d26a0e4
2 changed files with 10 additions and 0 deletions

View file

@ -33,6 +33,9 @@ Expressions can use the C-like operators
.TP .TP
.B < >= < <= == != .B < >= < <= == !=
.PP .PP
The \fB$\fR operator performs sign extension. \fIn\fB$\fIx\fR truncates \fIx\fR to \fIn\fR bits and sign extends.
If \fIn\fR is omitted, it is inferred from the highest set bit (the result is always ≤ 0 in this case).
.PP
Variables can be defined using Variables can be defined using
.BR = . .BR = .
The builtin variable The builtin variable

View file

@ -195,6 +195,10 @@ numbin(int op, Num *a, Num *b)
else else
mpassign(b, a); mpassign(b, a);
break; break;
case '$':
a->b = b->b;
mpxtend(b, mptoi(a), a);
break;
} }
numdecref(b); numdecref(b);
return a; return a;
@ -389,6 +393,7 @@ hexfix(Symbol *s)
%left unary %left unary
%left '*' '/' '%' %left '*' '/' '%'
%right LOEXP %right LOEXP
%right '$'
%{ %{
int save; int save;
@ -501,6 +506,7 @@ expr: LNUM
| '-' expr %prec unary { $$ = nummod($2); if($$ != nil) mpsub(mpzero, $$, $$); } | '-' expr %prec unary { $$ = nummod($2); if($$ != nil) mpsub(mpzero, $$, $$); }
| '~' expr %prec unary { $$ = nummod($2); if($$ != nil) mpnot($$, $$); } | '~' expr %prec unary { $$ = nummod($2); if($$ != nil) mpnot($$, $$); }
| '!' expr %prec unary { $$ = nummod($2); if($$ != nil) {itomp(mpcmp($$, mpzero) == 0, $$); $$->b = 0; } } | '!' expr %prec unary { $$ = nummod($2); if($$ != nil) {itomp(mpcmp($$, mpzero) == 0, $$); $$->b = 0; } }
| '$' expr { $$ = nummod($2); if($$ != nil) if($2->sign > 0) mpxtend($2, mpsignif($2), $$); else mpassign($2, $$); }
| expr '?' expr ':' expr %prec '?' { | expr '?' expr ':' expr %prec '?' {
if($1 == nil || mpcmp($1, mpzero) != 0){ if($1 == nil || mpcmp($1, mpzero) != 0){
$$ = $3; $$ = $3;
@ -541,6 +547,7 @@ expr: LNUM
if($$ == nil) error("no last result"); if($$ == nil) error("no last result");
else numincref($$); else numincref($$);
} }
| expr '$' expr { $$ = numbin('$', $1, $3); }
elist: { $$.n = 0; } | elist1 elist: { $$.n = 0; } | elist1
elist1: expr { $$.x[0] = $1; $$.n = 1; } elist1: expr { $$.x[0] = $1; $$.n = 1; }