diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 8dd7679..114a99a 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -50,6 +50,18 @@ namespace chaiscript return p1 % p2; } + template + Ret shift_left(P1 p1, P2 p2) + { + return p1 << p2; + } + + template + Ret shift_right(P1 p1, P2 p2) + { + return p1 >> p2; + } + template P1 &assign(P1 &p1, const P2 &p2) { @@ -717,6 +729,8 @@ namespace chaiscript opers_arithmetic_pod(m); m->add(fun(&detail::modulus), "%"); + m->add(fun(&detail::shift_left), "<<"); + m->add(fun(&detail::shift_right), ">>"); m->add(fun(&print), "print_string"); m->add(fun(&println), "println_string"); diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index d748e0c..ed527ec 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -24,7 +24,7 @@ namespace chaiscript class Token_Type { public: enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl, Expression, Comparison, Additive, Multiplicative, Negate, Not, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Map_Pair, Value_Range, - Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl }; }; + Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift }; }; namespace { @@ -35,7 +35,7 @@ namespace chaiscript const char *token_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", "Expression", "Comparison", "Additive", "Multiplicative", "Negate", "Not", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Map_Pair", "Value_Range", - "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl"}; + "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift"}; return token_types[tokentype]; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 526382b..e7b2526 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1100,6 +1100,7 @@ namespace chaiscript case (Token_Type::Comparison) : case (Token_Type::Additive) : case (Token_Type::Multiplicative) : + case (Token_Type::Shift) : return eval_comp_add_mul(ss, node); break; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index e40b85b..25d73f7 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1499,11 +1499,11 @@ namespace chaiscript int prev_stack_top = match_stack.size(); - if (Additive()) { + if (Shift()) { retval = true; if (Symbol(">=", true) || Symbol(">", true) || Symbol("<=", true) || Symbol("<", true) || Symbol("==", true) || Symbol("!=", true)) { do { - if (!Additive()) { + if (!Shift()) { throw Eval_Error("Incomplete comparison expression", File_Position(line, col), filename); } } while (retval && (Symbol(">=", true) || Symbol(">", true) || Symbol("<=", true) || Symbol("<", true) || Symbol("==", true) || Symbol("!=", true))); @@ -1587,6 +1587,30 @@ namespace chaiscript return retval; } + /** + * Top-level expression, parses a string of binary boolean operators from input + */ + bool Shift() { + bool retval = false; + + int prev_stack_top = match_stack.size(); + + if (Additive()) { + retval = true; + if (Symbol("<<", true) || Symbol(">>", true)) { + do { + if (!Additive()) { + throw Eval_Error("Incomplete shift expression", File_Position(line, col), filename); + } + } while (retval && (Symbol("<<", true) || Symbol(">>", true))); + + build_match(Token_Type::Shift, prev_stack_top); + } + } + + return retval; + } + /** * Top-level expression, parses a string of binary boolean operators from input */ diff --git a/unittests/shift.chai b/unittests/shift.chai new file mode 100644 index 0000000..bcbfa7c --- /dev/null +++ b/unittests/shift.chai @@ -0,0 +1 @@ +print(2 << 2) diff --git a/unittests/shift.txt b/unittests/shift.txt new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/unittests/shift.txt @@ -0,0 +1 @@ +8