summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAssaf Gordon <assafgordon@gmail.com>2014-12-04 03:11:42 (GMT)
committerAssaf Gordon <assafgordon@gmail.com>2014-12-04 03:11:42 (GMT)
commit8110636c06d50c7cf09db586a4f75da7cb7af166 (patch)
tree463fb2b7cb4f134ce3447bc3e2de64e8c303693c
parentc8081226656c2aba4238f2e421ca20a9ee50c179 (diff)
downloadagnostic-8110636c06d50c7cf09db586a4f75da7cb7af166.zip
agnostic-8110636c06d50c7cf09db586a4f75da7cb7af166.tar.gz
agnostic-8110636c06d50c7cf09db586a4f75da7cb7af166.tar.bz2
shell: implement unary orithmetic perators
-rw-r--r--src/node_modules/shell/shell_executor2.js35
-rw-r--r--src/shell_parser/posix_shell.pegjs35
-rw-r--r--src/tests/shell_executor_arithmetics.js4
3 files changed, 56 insertions, 18 deletions
diff --git a/src/node_modules/shell/shell_executor2.js b/src/node_modules/shell/shell_executor2.js
index 1eeaf7a..ea9cce5 100644
--- a/src/node_modules/shell/shell_executor2.js
+++ b/src/node_modules/shell/shell_executor2.js
@@ -1232,8 +1232,12 @@ function ArithmeticExpression(process_state, obj)
result = EnvVar(process_state, value);
break;
- case 'arithmetics_op_list':
- result = ArithmeticOpList(process_state,value);
+ case 'arithmetics_binary_op_list':
+ result = ArithmeticBinaryOpList(process_state,value);
+ break;
+
+ case 'arithmetic_unary_op_list':
+ result = ArithmeticUnaryOp(process_state,value);
break;
case 'arithmetic':
@@ -1261,11 +1265,34 @@ function ArithmeticExpression(process_state, obj)
return result;
}
+/* Process an unary operation */
+function ArithmeticUnaryOp(process_state, obj)
+{
+ ob_utils.VerifyArray(obj);
+ var operator = obj[0];
+ var operand = obj[1];
+ var value = ArithmeticExpression(process_state, operand);
+ switch (operator)
+ {
+ case '~': /* bitwise not */
+ value = ~value;
+ break;
+
+ case '!': /* logical not */
+ value = (value==0)?1:0;
+ break;
+
+ default:
+ throw "Invalid arithmetic unary operator: " + operator ;
+ }
+ return value;
+}
+
/* Process an list of arithmetics operation, with the same precedence
(eg. a list of addition/substractions, or a list of multiplications/divisions).
During execution/emulation, 'value' should contain the accumulated value */
-function ArithmeticOpList(process_state, obj)
+function ArithmeticBinaryOpList(process_state, obj)
{
ob_utils.VerifyArray(obj);
var operand = obj[0];
@@ -1356,7 +1383,7 @@ function ArithmeticOpList(process_state, obj)
break;
default:
- throw "Invalid arithmetic operator: " + operator ;
+ throw "Invalid arithmetic binary operator: " + operator ;
}
}
diff --git a/src/shell_parser/posix_shell.pegjs b/src/shell_parser/posix_shell.pegjs
index b9ed02b..3169bd7 100644
--- a/src/shell_parser/posix_shell.pegjs
+++ b/src/shell_parser/posix_shell.pegjs
@@ -87,7 +87,7 @@ function pack_simple_command(prefix,cmd,suffix)
return { "SimpleCommand" : command } ;
}
-function arithmatic_op(first,rest)
+function arithmatic_binary_op(first,rest)
{
if (rest.length===0)
return first;
@@ -98,7 +98,7 @@ function arithmatic_op(first,rest)
list.push( rest[i][1] ); // the operator
list.push( rest[i][3] ); // the value
}
- return { "arithmetics_op_list" : list } ;
+ return { "arithmetics_binary_op_list" : list } ;
}
}
@@ -678,51 +678,58 @@ ArithmeticExpression =
LogicalOrTerm
= first:LogicalAndTerm
rest:( whitespace "||" whitespace LogicalAndTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
LogicalAndTerm
= first:BitwiseOrTerm
rest:( whitespace "&&" whitespace BitwiseOrTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
BitwiseOrTerm
= first:BitwiseXorTerm
rest:( whitespace "|" whitespace BitwiseXorTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
BitwiseXorTerm
= first:BitwiseAndTerm
rest:( whitespace "^" whitespace BitwiseAndTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
BitwiseAndTerm
= first:EqualityOpTerm
rest:( whitespace "&" whitespace EqualityOpTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
EqualityOpTerm
= first:RelationalOpTerm
rest:( whitespace ("==" / "!=" ) whitespace RelationalOpTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
RelationalOpTerm
= first:BitwiseShiftTerm
rest:( whitespace ( "<=" / ">=" / ">" / "<" ) whitespace BitwiseShiftTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
BitwiseShiftTerm
= first:AdditiveTerm
rest:( whitespace (">>" / "<<") whitespace AdditiveTerm)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
AdditiveTerm
= first:Term rest:( whitespace ("+" / "-") whitespace Term)*
- { return arithmatic_op(first,rest) ; }
+ { return arithmatic_binary_op(first,rest) ; }
Term
- = first:Factor rest:( whitespace ("*" / "/" / "%") whitespace Factor)*
- { return arithmatic_op(first,rest) ; }
-
+ = first:UnaryOpTerm rest:( whitespace ("*" / "/" / "%") whitespace UnaryOpTerm)*
+ { return arithmatic_binary_op(first,rest) ; }
+
+UnaryOpTerm
+ = op:( "!" / "~" )? whitespace term:Factor
+ {
+ if (op===null)
+ return term;
+ return { "arithmetic_unary_op_list" : [ op, term ] };
+ }
Factor
= "(" whitespace expr:ArithmeticExpression whitespace ")" { return expr ; }
diff --git a/src/tests/shell_executor_arithmetics.js b/src/tests/shell_executor_arithmetics.js
index c736a98..0a9096b 100644
--- a/src/tests/shell_executor_arithmetics.js
+++ b/src/tests/shell_executor_arithmetics.js
@@ -68,6 +68,10 @@ var tests = [
[ "v21","echo $((1^2))", { stdout: [ "3" ] } ],
[ "v22","echo $((42&&9))", { stdout: [ "1" ] } ],
[ "v23","echo $((100||0))", { stdout: [ "1" ] } ],
+[ "v24","echo $((!0))", { stdout: [ "1" ] } ],
+[ "v25","echo $((!90))", { stdout: [ "0" ] } ],
+[ "v26","echo $((~7))", { stdout: [ "-8" ] } ],
+[ "v27","echo $((15&~7))", { stdout: [ "8" ] } ],
//Test (some) operator precedences
//This corresponds to the order of the operators listed in