From bb174b37a64b49ce441dbf5b0cdfc806220fc5e9 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Wed, 1 Jul 2009 13:19:26 +0000 Subject: [PATCH] Added inline map creation --- chaiscript/chaiscript.hpp | 4 +- chaiscript/chaiscript_engine.hpp | 6 +-- chaiscript/chaiscript_eval.hpp | 18 ++++---- chaiscript/chaiscript_parser.hpp | 74 ++++++++++++++++++++++++++++++-- chaiscript/main.cpp | 2 +- 5 files changed, 83 insertions(+), 21 deletions(-) diff --git a/chaiscript/chaiscript.hpp b/chaiscript/chaiscript.hpp index 7bae7c92..090af6d0 100644 --- a/chaiscript/chaiscript.hpp +++ b/chaiscript/chaiscript.hpp @@ -39,12 +39,12 @@ namespace chaiscript */ class Token_Type { public: enum Type { Error, Int, Float, Id, Char, Str, Eol, 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 }; }; + Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Map_Pair }; }; const char *token_type_to_string(int tokentype) { const char *token_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "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" }; + "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Map_Pair" }; return token_types[tokentype]; } diff --git a/chaiscript/chaiscript_engine.hpp b/chaiscript/chaiscript_engine.hpp index abf5600c..2a1428f5 100644 --- a/chaiscript/chaiscript_engine.hpp +++ b/chaiscript/chaiscript_engine.hpp @@ -85,11 +85,9 @@ namespace chaiscript dispatchkit::Boxed_Value value; try { - parser.clear_match_stack(); if (parser.parse(input, filename)) { - //show_match_stack(); + //parser.show_match_stack(); value = eval_token(engine, parser.ast()); - //clear_match_stack(); } } catch (const ReturnValue &rv) { @@ -97,7 +95,6 @@ namespace chaiscript } catch (Parse_Error &pe) { std::cout << pe.reason << " in " << pe.filename << " at " << pe.position.line << ", " << pe.position.column << std::endl; - parser.clear_match_stack(); } catch (EvalError &ee) { if (filename != std::string("__EVAL__")) { @@ -110,6 +107,7 @@ namespace chaiscript catch (std::exception &e) { std::cout << "Exception: " << e.what() << std::endl; } + parser.clear_match_stack(); return value; } diff --git a/chaiscript/chaiscript_eval.hpp b/chaiscript/chaiscript_eval.hpp index 413e2376..8179d3bc 100644 --- a/chaiscript/chaiscript_eval.hpp +++ b/chaiscript/chaiscript_eval.hpp @@ -186,27 +186,25 @@ namespace chaiscript } } break; - /* - case (TokenType::Map_Init) : { + case (Token_Type::Inline_Map) : { try { retval = dispatch(ss.get_function("Map"), dispatchkit::Param_List_Builder()); - for (i = 0; i < node->children.size(); ++i) { + for (i = 0; i < node->children[0]->children.size(); ++i) { try { - dispatchkit::Boxed_Value key = eval_token(ss, node->children[i]->children[0]); + dispatchkit::Boxed_Value key = eval_token(ss, node->children[0]->children[i]->children[0]); dispatchkit::Boxed_Value slot = dispatch(ss.get_function("[]"), dispatchkit::Param_List_Builder() << retval << key); - dispatch(ss.get_function("="), dispatchkit::Param_List_Builder() << slot << eval_token(ss, node->children[i]->children[1])); + dispatch(ss.get_function("="), dispatchkit::Param_List_Builder() << slot << eval_token(ss, node->children[0]->children[i]->children[1])); } catch (const dispatchkit::dispatch_error &inner_e) { - throw EvalError("Can not find appropriate '=' for map init", node->children[i]); + throw EvalError("Can not find appropriate '=' for map init", node->children[0]->children[i]); } } } catch (const dispatchkit::dispatch_error &e) { - throw EvalError("Can not find appropriate 'Vector()'", node); + throw EvalError("Can not find appropriate 'Map()'", node); } } break; - */ case (Token_Type::Fun_Call) : { dispatchkit::Param_List_Builder plb; @@ -461,11 +459,11 @@ namespace chaiscript throw ReturnValue(retval, node); } break; - /* - case (TokenType::Break) : { + case (Token_Type::Break) : { throw BreakLoop(node); } break; + /* case (TokenType::Statement) : case (TokenType::Carriage_Return) : case (TokenType::Semicolon) : diff --git a/chaiscript/chaiscript_parser.hpp b/chaiscript/chaiscript_parser.hpp index ec09c8eb..24811afd 100644 --- a/chaiscript/chaiscript_parser.hpp +++ b/chaiscript/chaiscript_parser.hpp @@ -613,6 +613,27 @@ namespace chaiscript } + bool Container_Arg_List() { + bool retval = false; + + int prev_stack_top = match_stack.size(); + + if (Map_Pair()) { + retval = true; + if (Char(',')) { + do { + if (!Map_Pair()) { + throw Parse_Error("Unexpected value in container", match_stack.back()); + } + } while (retval && Char(',')); + } + build_match(Token_Type::Arg_List, prev_stack_top); + } + + return retval; + + } + bool Lambda() { bool retval = false; @@ -762,6 +783,20 @@ namespace chaiscript return retval; } + bool Break() { + bool retval = false; + + int prev_stack_top = match_stack.size(); + + if (Keyword("break")) { + retval = true; + + build_match(Token_Type::Break, prev_stack_top); + } + + return retval; + } + bool Id_Fun_Array() { bool retval = false; std::string::iterator prev_pos = input_pos; @@ -852,11 +887,21 @@ namespace chaiscript if (Char('[')) { retval = true; - Arg_List(); + Container_Arg_List(); if (!Char(']')) { throw Parse_Error("Missing closing square bracket", File_Position(line, col), filename); } - build_match(Token_Type::Inline_Array, prev_stack_top); + if ((prev_stack_top != match_stack.size()) && (match_stack.back()->children.size() > 0)) { + if (match_stack.back()->children[0]->identifier == Token_Type::Map_Pair) { + build_match(Token_Type::Inline_Map, prev_stack_top); + } + else { + build_match(Token_Type::Inline_Array, prev_stack_top); + } + } + else { + build_match(Token_Type::Inline_Array, prev_stack_top); + } } return retval; @@ -1058,7 +1103,7 @@ namespace chaiscript if (Symbol("&&", true) || Symbol("||", true)) { do { if (!Comparison()) { - throw Parse_Error("Incomplete expression", File_Position(line, col), filename); + throw Parse_Error("Incomplete expression", File_Position(line, col), filename); } } while (retval && (Symbol("&&", true) || Symbol("||", true))); @@ -1069,6 +1114,27 @@ namespace chaiscript return retval; } + bool Map_Pair() { + bool retval = false; + + int prev_stack_top = match_stack.size(); + + if (Expression()) { + retval = true; + if (Symbol(":")) { + do { + if (!Expression()) { + throw Parse_Error("Incomplete map pair", File_Position(line, col), filename); + } + } while (retval && Symbol(":")); + + build_match(Token_Type::Map_Pair, prev_stack_top); + } + } + + return retval; + } + bool Equation() { bool retval = false; @@ -1090,7 +1156,7 @@ namespace chaiscript } bool Statement() { - if (Return() || Equation()) { + if (Return() || Break() || Equation()) { return true; } else { diff --git a/chaiscript/main.cpp b/chaiscript/main.cpp index 3a3a0852..a550a599 100644 --- a/chaiscript/main.cpp +++ b/chaiscript/main.cpp @@ -26,7 +26,7 @@ int main(int argc, char *argv[]) { dispatchkit::dispatch(chai.get_eval_engine().get_function("print"), dispatchkit::Param_List_Builder() << printeval); } catch (const std::runtime_error &e) { - std::cout << "result: object #" << &val << " Error: " << e.what() << std::endl; + //std::cout << "result: object #" << &val << " Error: " << e.what() << std::endl; } } std::cout << "eval> ";