From 454d26a0e4f91d03bb8f1f4f3f7dbe56d722deab Mon Sep 17 00:00:00 2001 From: aiju Date: Fri, 4 May 2018 11:07:39 +0100 Subject: [PATCH] pc: add $ operator --- sys/man/1/pc | 3 +++ sys/src/cmd/pc.y | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/sys/man/1/pc b/sys/man/1/pc index 26ae25690..287938541 100644 --- a/sys/man/1/pc +++ b/sys/man/1/pc @@ -33,6 +33,9 @@ Expressions can use the C-like operators .TP .B < >= < <= == != .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 .BR = . The builtin variable diff --git a/sys/src/cmd/pc.y b/sys/src/cmd/pc.y index 039498d03..7592f578b 100644 --- a/sys/src/cmd/pc.y +++ b/sys/src/cmd/pc.y @@ -195,6 +195,10 @@ numbin(int op, Num *a, Num *b) else mpassign(b, a); break; + case '$': + a->b = b->b; + mpxtend(b, mptoi(a), a); + break; } numdecref(b); return a; @@ -389,6 +393,7 @@ hexfix(Symbol *s) %left unary %left '*' '/' '%' %right LOEXP +%right '$' %{ int save; @@ -501,6 +506,7 @@ expr: LNUM | '-' expr %prec unary { $$ = nummod($2); if($$ != nil) mpsub(mpzero, $$, $$); } | '~' expr %prec unary { $$ = nummod($2); if($$ != nil) mpnot($$, $$); } | '!' 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 '?' { if($1 == nil || mpcmp($1, mpzero) != 0){ $$ = $3; @@ -541,6 +547,7 @@ expr: LNUM if($$ == nil) error("no last result"); else numincref($$); } + | expr '$' expr { $$ = numbin('$', $1, $3); } elist: { $$.n = 0; } | elist1 elist1: expr { $$.x[0] = $1; $$.n = 1; }