diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index a5212a4..eb3a897 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -126,10 +126,12 @@ namespace chaiscript multiplication.push_back("%"); m_operator_matches.push_back(multiplication); + /* m_operators.push_back(AST_Node_Type::Dot_Access); std::vector dot_access; dot_access.push_back("."); m_operator_matches.push_back(dot_access); + */ for ( int c = 0 ; c < detail::lengthof_alphabet ; ++c ) { for ( int a = 0 ; a < detail::max_alphabet ; a ++ ) { @@ -1479,14 +1481,15 @@ namespace chaiscript } /** - * Reads an identifier, then proceeds to check if it's a function or array call + * Reads an dot expression(member access), then proceeds to check if it's a function or array call */ - bool Id_Fun_Array() { + bool Dot_Fun_Array() { bool retval = false; std::string::const_iterator prev_pos = m_input_pos; size_t prev_stack_top = m_match_stack.size(); - if (Id(true)) { + if (Lambda() || Num(true) || Quoted_String(true) || Single_Quoted_String(true) || + Paren_Expression() || Inline_Container() || Id(true)) { retval = true; bool has_more = true; @@ -1502,6 +1505,19 @@ namespace chaiscript } build_match(AST_NodePtr(new eval::Fun_Call_AST_Node()), prev_stack_top); + //FIXME: Work around for method calls until we have a better solution + if (!m_match_stack.back()->children.empty()) { + if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Dot_Access) { + AST_NodePtr dot_access = m_match_stack.back()->children[0]; + AST_NodePtr func_call = m_match_stack.back(); + m_match_stack.pop_back(); + func_call->children.erase(func_call->children.begin()); + func_call->children.insert(func_call->children.begin(), dot_access->children.back()); + dot_access->children.pop_back(); + dot_access->children.push_back(func_call); + m_match_stack.push_back(dot_access); + } + } } else if (Char('[')) { has_more = true; @@ -1512,6 +1528,14 @@ namespace chaiscript build_match(AST_NodePtr(new eval::Array_Call_AST_Node()), prev_stack_top); } + else if (Symbol(".", true)) { + has_more = true; + if (!(Id(true))) { + throw exception::eval_error("Incomplete array access", File_Position(m_line, m_col), *m_filename); + } + + build_match(AST_NodePtr(new eval::Dot_Access_AST_Node()), prev_stack_top); + } } } @@ -1676,8 +1700,9 @@ namespace chaiscript * Parses any of a group of 'value' style ast_node groups from input */ bool Value() { - if (Var_Decl() || Lambda() || Id_Fun_Array() || Num(true) || Prefix() || Quoted_String(true) || Single_Quoted_String(true) || - Paren_Expression() || Inline_Container()) { + if (Var_Decl() || /*Lambda() ||*/ Dot_Fun_Array() || /*Num(true) ||*/ Prefix() /*|| + Quoted_String(true) || Single_Quoted_String(true) || + Paren_Expression() || Inline_Container()*/) { return true; } else { @@ -1714,9 +1739,11 @@ namespace chaiscript case(AST_Node_Type::Comparison) : build_match(AST_NodePtr(new eval::Comparison_AST_Node()), prev_stack_top); break; + /* case(AST_Node_Type::Dot_Access) : build_match(AST_NodePtr(new eval::Dot_Access_AST_Node()), prev_stack_top); break; + */ case(AST_Node_Type::Addition) : oper = m_match_stack.at(m_match_stack.size()-2); m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, diff --git a/readme.txt b/readme.txt index a11e661..bddc703 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Release under the BSD license, see "license.txt" for details. [Introduction] -ChaiScript is the only embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development techniques, working with the developer like he expects it to work. Being a native C++ application, it has some advantages over existing embedded scripting languages: +ChaiScript is one of the only embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development techniques, working with the developer like he expects it to work. Being a native C++ application, it has some advantages over existing embedded scripting languages: 1) It uses a header-only approach, which makes it easy to integrate with existing projects. 2) It maintains type safety between your C++ application and the user scripts. diff --git a/unittests/function_array_adjacent.chai b/unittests/function_array_adjacent.chai new file mode 100644 index 0000000..c34e2be --- /dev/null +++ b/unittests/function_array_adjacent.chai @@ -0,0 +1 @@ +assert_equal(2, `+`.get_contained_functions()[0].get_arity()) diff --git a/unittests/vector_literal_acccess.chai b/unittests/vector_literal_acccess.chai new file mode 100644 index 0000000..29a7c05 --- /dev/null +++ b/unittests/vector_literal_acccess.chai @@ -0,0 +1 @@ +assert_equal(1, [1,2,3][0]) diff --git a/unittests/vector_of_one.chai b/unittests/vector_of_one.chai new file mode 100644 index 0000000..f4bb01b --- /dev/null +++ b/unittests/vector_of_one.chai @@ -0,0 +1,2 @@ +var x = [1] +assert_equal(1, x[0]) diff --git a/unittests/vector_paren_literal_access.chai b/unittests/vector_paren_literal_access.chai new file mode 100644 index 0000000..a0c6b96 --- /dev/null +++ b/unittests/vector_paren_literal_access.chai @@ -0,0 +1 @@ +assert_equal(1, ([1,2,3])[0])