diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 6b5d132..4543b40 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -22,9 +22,9 @@ namespace chaiscript * Types of AST nodes available to the parser and eval */ class Token_Type { public: enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl, - Comparison, Additive, Multiplicative, Negate, Not, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, + Comparison, Additive, Multiplicative, Unary_Minus, Unary_Plus, 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, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, + Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, Bitwise_Not, Logical_And, Logical_Or}; }; namespace @@ -34,9 +34,9 @@ namespace chaiscript */ const char *token_type_to_string(int tokentype) { const char *token_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", - "Comparison", "Additive", "Multiplicative", "Negate", "Not", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String", + "Comparison", "Additive", "Multiplicative", "Unary_Minus", "Unary_Plus", "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", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", + "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", "Bitwise_Not", "Logical_And", "Logical_Or"}; return token_types[tokentype]; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 3a639db..1061978 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -338,7 +338,7 @@ namespace chaiscript * Evaluates a unary negation */ template - Boxed_Value eval_negate(Eval_System &ss, const TokenPtr &node) { + Boxed_Value eval_unary_minus(Eval_System &ss, const TokenPtr &node) { Boxed_Value retval = eval_token(ss, node->children[0]); Param_List_Builder plb; plb << retval; @@ -348,8 +348,30 @@ namespace chaiscript return ss.call_function("*", plb); } catch(std::exception &){ - throw Eval_Error("Can not find appropriate negation", node->children[0]); + throw Eval_Error("Can not find appropriate unary minus", node->children[0]); } + + /* + * Should be unary minus + */ + } + + /** + * Evaluates a unary negation + */ + template + Boxed_Value eval_unary_plus(Eval_System &ss, const TokenPtr &node) { + Boxed_Value retval = eval_token(ss, node->children[0]); + Param_List_Builder plb; + plb << retval; + + try { + return ss.call_function("+", plb); + } + catch(std::exception &){ + throw Eval_Error("Can not find appropriate unary plus", node->children[0]); + } + } /** @@ -363,6 +385,25 @@ namespace chaiscript catch (const bad_boxed_cast &) { throw Eval_Error("Boolean not('!') condition not boolean", node->children[0]); } + /* + * Should be like above, but use ! + */ + } + + /** + * Evaluates a unary boolean not + */ + template + Boxed_Value eval_bitwise_not(Eval_System &ss, const TokenPtr &node) { + try { + return Boxed_Value(~boxed_cast(eval_token(ss, node->children[0]))); + } + catch (const bad_boxed_cast &) { + throw Eval_Error("Bitwise not condition not integer", node->children[0]); + } + /* + * Should be like above, but use ~ + */ } /** @@ -1113,14 +1154,22 @@ namespace chaiscript return eval_array_call(ss, node); break; - case (Token_Type::Negate) : - return eval_negate(ss, node); + case (Token_Type::Unary_Minus) : + return eval_unary_minus(ss, node); + break; + + case (Token_Type::Unary_Plus) : + return eval_unary_plus(ss, node); break; case (Token_Type::Not) : return eval_not(ss, node); break; + case (Token_Type::Bitwise_Not) : + return eval_bitwise_not(ss, node); + break; + case (Token_Type::Prefix) : return eval_prefix(ss, node); break; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index dea1110..7a45371 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1515,10 +1515,19 @@ namespace chaiscript retval = true; if (!Operator(operators.size()-1)) { - throw Eval_Error("Incomplete negation expression", File_Position(line, col), filename); + throw Eval_Error("Incomplete unary - expression", File_Position(line, col), filename); } - build_match(Token_Type::Negate, prev_stack_top); + build_match(Token_Type::Unary_Minus, prev_stack_top); + } + else if (Char('+')) { + retval = true; + + if (!Operator(operators.size()-1)) { + throw Eval_Error("Incomplete unary + expression", File_Position(line, col), filename); + } + + build_match(Token_Type::Unary_Plus, prev_stack_top); } else if (Char('!')) { retval = true; @@ -1529,6 +1538,15 @@ namespace chaiscript build_match(Token_Type::Not, prev_stack_top); } + else if (Char('~')) { + retval = true; + + if (!Operator(operators.size()-1)) { + throw Eval_Error("Incomplete '~' expression", File_Position(line, col), filename); + } + + build_match(Token_Type::Bitwise_Not, prev_stack_top); + } return retval; }