diff --git a/chaiscript/chaiscript.hpp b/chaiscript/chaiscript.hpp index fa039d9..1d0e84b 100644 --- a/chaiscript/chaiscript.hpp +++ b/chaiscript/chaiscript.hpp @@ -12,20 +12,24 @@ #include #include -class TokenType { public: enum Type { File, Whitespace, Identifier, Integer, Operator, Parens_Open, Parens_Close, - Square_Open, Square_Close, Curly_Open, Curly_Close, Comma, Quoted_String, Single_Quoted_String, Carriage_Return, Semicolon, - Function_Def, Lambda_Def, Scoped_Block, Statement, Equation, Return, Expression, Term, Factor, Negate, Not, Comment, - Value, Fun_Call, Method_Call, Comparison, If_Block, While_Block, Boolean, Real_Number, Array_Call, Variable_Decl, Array_Init, - For_Block, Prefix, Break }; }; +namespace chaiscript +{ -const char *tokentype_to_string(int tokentype) { - const char *token_types[] = {"File", "Whitespace", "Identifier", "Integer", "Operator", "Parens_Open", "Parens_Close", - "Square_Open", "Square_Close", "Curly_Open", "Curly_Close", "Comma", "Quoted_String", "Single_Quoted_String", "Carriage_Return", "Semicolon", - "Function_Def", "Lambda_Def", "Scoped_Block", "Statement", "Equation", "Return", "Expression", "Term", "Factor", "Negate", "Not", "Comment", - "Value", "Fun_Call", "Method_Call", "Comparison", "If_Block", "While_Block", "Boolean", "Real Number", "Array_Call", "Variable_Decl", "Array_Init", - "For_Block", "Prefix", "Break" }; + class TokenType { public: enum Type { File, Whitespace, Identifier, Integer, Operator, Parens_Open, Parens_Close, + Square_Open, Square_Close, Curly_Open, Curly_Close, Comma, Quoted_String, Single_Quoted_String, Carriage_Return, Semicolon, + Function_Def, Lambda_Def, Scoped_Block, Statement, Equation, Return, Expression, Term, Factor, Negate, Not, Comment, + Value, Fun_Call, Method_Call, Comparison, If_Block, While_Block, Boolean, Real_Number, Array_Call, Variable_Decl, Array_Init, + For_Block, Prefix, Break }; }; - return token_types[tokentype]; + const char *tokentype_to_string(int tokentype) { + const char *token_types[] = {"File", "Whitespace", "Identifier", "Integer", "Operator", "Parens_Open", "Parens_Close", + "Square_Open", "Square_Close", "Curly_Open", "Curly_Close", "Comma", "Quoted_String", "Single_Quoted_String", "Carriage_Return", "Semicolon", + "Function_Def", "Lambda_Def", "Scoped_Block", "Statement", "Equation", "Return", "Expression", "Term", "Factor", "Negate", "Not", "Comment", + "Value", "Fun_Call", "Method_Call", "Comparison", "If_Block", "While_Block", "Boolean", "Real Number", "Array_Call", "Variable_Decl", "Array_Init", + "For_Block", "Prefix", "Break" }; + + return token_types[tokentype]; + } } #include "dispatchkit.hpp" diff --git a/chaiscript/chaiscript_engine.hpp b/chaiscript/chaiscript_engine.hpp index 7327adc..3e7f791 100644 --- a/chaiscript/chaiscript_engine.hpp +++ b/chaiscript/chaiscript_engine.hpp @@ -6,268 +6,268 @@ #include -//A function that prints any string passed to it +namespace chaiscript +{ + template + class ChaiScript_System { + langkit::Lexer lexer; + langkit::Rule parser; + Eval_Engine engine; -template -class ChaiScript_System { - langkit::Lexer lexer; - langkit::Rule parser; - Eval_Engine engine; + public: + ChaiScript_System() : lexer(build_lexer()), parser(build_parser_rules()), engine(build_eval_system(lexer, parser)) { -public: - ChaiScript_System() : lexer(build_lexer()), parser(build_parser_rules()), engine(build_eval_system(lexer, parser)) { - - } - - Eval_Engine &get_eval_engine() { - return engine; - } - - const dispatchkit::Boxed_Value eval(const std::vector &vals) { - std::string val; - - try { - val = dispatchkit::Cast_Helper()(vals[0]); - } - catch (std::exception &e) { - throw EvalError("Can not evaluate string: " + val, langkit::TokenPtr()); - } - catch (EvalError &ee) { - throw EvalError("Can not evaluate string: " + val + " reason: " + ee.reason, langkit::TokenPtr()); - } - return evaluate_string(val); - } - - std::string load_file(const char *filename) { - std::ifstream infile (filename, std::ios::in | std::ios::ate); - - if (!infile.is_open()) { - std::string fname = filename; - throw std::runtime_error("Can not open: " + fname); } - std::streampos size = infile.tellg(); - infile.seekg(0, std::ios::beg); - - std::vector v(size); - infile.read(&v[0], size); - - std::string ret_val (v.empty() ? std::string() : std::string (v.begin(), v.end()).c_str()); - - return ret_val; - } - - void debug_print(langkit::TokenPtr token, std::string prepend) { - using namespace langkit; - std::cout << prepend << "Token: " << token->text << "(" << tokentype_to_string(token->identifier) << ") @ " << token->filename - << ": (" << token->start.line << ", " << token->start.column << ") to (" - << token->end.line << ", " << token->end.column << ") " << std::endl; - - for (unsigned int i = 0; i < token->children.size(); ++i) { - debug_print(token->children[i], prepend + " "); + Eval_Engine &get_eval_engine() { + return engine; } - } - void debug_print(std::vector &tokens) { - using namespace langkit; - for (unsigned int i = 0; i < tokens.size(); ++i) { - debug_print(tokens[i], ""); + const dispatchkit::Boxed_Value eval(const std::vector &vals) { + std::string val; + + try { + val = dispatchkit::Cast_Helper()(vals[0]); + } + catch (std::exception &e) { + throw EvalError("Can not evaluate string: " + val, langkit::TokenPtr()); + } + catch (EvalError &ee) { + throw EvalError("Can not evaluate string: " + val + " reason: " + ee.reason, langkit::TokenPtr()); + } + return evaluate_string(val); } - } - langkit::Lexer build_lexer() { - using namespace langkit; - Lexer lexer; - lexer.set_skip(Pattern("[ \\t]+", TokenType::Whitespace)); - lexer.set_line_sep(Pattern("\\n|\\r\\n", TokenType::Carriage_Return)); - lexer.set_command_sep(Pattern(";|\\r\\n|\\n", TokenType::Semicolon)); - lexer.set_multiline_comment(Pattern("/\\*", TokenType::Comment), Pattern("\\*/", TokenType::Comment)); - lexer.set_singleline_comment(Pattern("//", TokenType::Comment)); + std::string load_file(const char *filename) { + std::ifstream infile (filename, std::ios::in | std::ios::ate); - lexer << Pattern("[A-Za-z_][A-Za-z_0-9]*", TokenType::Identifier); - lexer << Pattern("[0-9]+\\.[0-9]+", TokenType::Real_Number); - lexer << Pattern("[0-9]+", TokenType::Integer); - lexer << Pattern("[!@#$%^&*|\\-+=<>.]+|/[!@#$%^&|\\-+=<>]*", TokenType::Operator); - lexer << Pattern("\\(", TokenType::Parens_Open); - lexer << Pattern("\\)", TokenType::Parens_Close); - lexer << Pattern("\\[", TokenType::Square_Open); - lexer << Pattern("\\]", TokenType::Square_Close); - lexer << Pattern("\\{", TokenType::Curly_Open); - lexer << Pattern("\\}", TokenType::Curly_Close); - lexer << Pattern(",", TokenType::Comma); - lexer << Pattern("\"(?:[^\"\\\\]|\\\\.)*\"", TokenType::Quoted_String); - lexer << Pattern("'(?:[^'\\\\]|\\\\.)*'", TokenType::Single_Quoted_String); + if (!infile.is_open()) { + std::string fname = filename; + throw std::runtime_error("Can not open: " + fname); + } - return lexer; - } + std::streampos size = infile.tellg(); + infile.seekg(0, std::ios::beg); - langkit::Rule build_parser_rules() { - using namespace langkit; - Rule params; - Rule block(TokenType::Scoped_Block); - Rule fundef(TokenType::Function_Def); - Rule lambda_def(TokenType::Lambda_Def); - Rule statement; - Rule equation(TokenType::Equation); - Rule boolean(TokenType::Boolean); - Rule comparison(TokenType::Comparison); - Rule expression(TokenType::Expression); - Rule term(TokenType::Term); - Rule factor(TokenType::Factor); - Rule negate(TokenType::Negate); - Rule boolean_not(TokenType::Not); - Rule prefix(TokenType::Prefix); + std::vector v(size); + infile.read(&v[0], size); - Rule funcall(TokenType::Fun_Call); - Rule methodcall(TokenType::Method_Call); - Rule if_block(TokenType::If_Block); - Rule while_block(TokenType::While_Block); - Rule for_block(TokenType::For_Block); - Rule arraycall(TokenType::Array_Call); - Rule vardecl(TokenType::Variable_Decl); - Rule arrayinit(TokenType::Array_Init); + std::string ret_val (v.empty() ? std::string() : std::string (v.begin(), v.end()).c_str()); - Rule return_statement(TokenType::Return); - Rule break_statement(TokenType::Break); - - Rule value; - Rule statements; - Rule for_conditions; - Rule source_elem; - Rule source_elems; - Rule statement_list; - Rule paren_block; - - Rule rule = *(Ign(Id(TokenType::Semicolon))) >> source_elems >> *(Ign(Id(TokenType::Semicolon))); - - source_elems = source_elem >> *(+Ign(Id(TokenType::Semicolon)) >> source_elem); - source_elem = fundef | statement; - statement_list = statement >> *(+Ign(Id(TokenType::Semicolon)) >> statement); - statement = if_block | while_block | for_block | equation; - - if_block = Ign(Str("if")) >> boolean >> block >> *(*Ign(Id(TokenType::Semicolon)) >> Str("elseif") >> boolean >> block) >> ~(*Ign(Id(TokenType::Semicolon)) >> Str("else") >> block); - while_block = Ign(Str("while")) >> boolean >> block; - for_block = Ign(Str("for")) >> for_conditions >> block; - for_conditions = Ign(Id(TokenType::Parens_Open)) >> ~equation >> Ign(Str(";")) >> boolean >> Ign(Str(";")) >> equation >> Ign(Id(TokenType::Parens_Close)); - - fundef = Ign(Str("def")) >> Id(TokenType::Identifier) >> ~(Ign(Id(TokenType::Parens_Open)) >> ~params >> Ign(Id(TokenType::Parens_Close))) >> - block; - params = Id(TokenType::Identifier) >> *(Ign(Str(",")) >> Id(TokenType::Identifier)); - block = *(Ign(Id(TokenType::Semicolon))) >> Ign(Id(TokenType::Curly_Open)) >> *(Ign(Id(TokenType::Semicolon))) >> ~statement_list >> *(Ign(Id(TokenType::Semicolon))) >> Ign(Id(TokenType::Curly_Close)); - - equation = *(((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("=")) | - ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("+=")) | - ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("-=")) | - ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("*=")) | - ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("/="))) >> boolean; - boolean = comparison >> *((Str("&&") >> comparison) | (Str("||") >> comparison)); - comparison = expression >> *((Str("==") >> expression) | (Str("!=") >> expression) | (Str("<") >> expression) | - (Str("<=") >> expression) |(Str(">") >> expression) | (Str(">=") >> expression)); - expression = term >> *((Str("+") >> term) | (Str("-") >> term)); - term = factor >> *((Str("*") >> factor) | (Str("/") >> factor)); - factor = methodcall | arraycall | value | negate | boolean_not | prefix | (Ign(Str("+")) >> value); - value = vardecl | arrayinit | block | paren_block | lambda_def | return_statement | break_statement | - funcall | Id(TokenType::Identifier) | Id(TokenType::Real_Number) | Id(TokenType::Integer) | Id(TokenType::Quoted_String) | - Id(TokenType::Single_Quoted_String) ; - - funcall = Id(TokenType::Identifier) >> Ign(Id(TokenType::Parens_Open)) >> ~(boolean >> *(Ign(Str("," )) >> boolean)) >> Ign(Id(TokenType::Parens_Close)); - methodcall = value >> +(Ign(Str(".")) >> funcall); - negate = (Str("-") >> (boolean | arraycall)); - boolean_not = (Str("!") >> (boolean | arraycall)); - prefix = (Str("++") >> (boolean | arraycall)) | (Str("--") >> (boolean | arraycall)); - arraycall = value >> +((Ign(Id(TokenType::Square_Open)) >> boolean >> Ign(Id(TokenType::Square_Close)))); - - arrayinit = Ign(Id(TokenType::Square_Open)) >> ~(boolean >> *(Ign(Str(",")) >> boolean)) >> Ign(Id(TokenType::Square_Close)); - vardecl = Ign(Str("var")) >> Id(TokenType::Identifier); - return_statement = Ign(Str("return")) >> ~boolean; - break_statement = Wrap(Ign(Str("break"))); - paren_block = (Ign(Id(TokenType::Parens_Open)) >> equation >> Ign(Id(TokenType::Parens_Close))); - lambda_def = Ign(Str("function")) >> ~(Ign(Id(TokenType::Parens_Open)) >> ~params >> Ign(Id(TokenType::Parens_Close))) >> block; - - return rule; - } - - - Eval_Engine build_eval_system(langkit::Lexer &lexer, langkit::Rule &parser) { - using namespace langkit; - Eval_Engine ss; - dispatchkit::Bootstrap::bootstrap(ss); - dispatchkit::bootstrap_vector >(ss, "Vector"); - - ss.register_function(boost::shared_ptr( - new dispatchkit::Dynamic_Proxy_Function(boost::bind(&ChaiScript_System::eval, boost::ref(*this), _1), 1)), "eval"); - - evaluate_string("def print(x) { print_string(x.to_string()) } "); - - return ss; - } - - langkit::TokenPtr parse(langkit::Rule &rule, std::vector &tokens, const char *filename) { - using namespace langkit; - - Token_Iterator iter = tokens.begin(), end = tokens.end(); - TokenPtr parent(new Token("Root", TokenType::File, filename)); - - std::pair results = rule(iter, end, parent); - - if ((results.second) && (results.first == end)) { - //debug_print(parent, ""); - return parent; + return ret_val; } - else { - throw ParserError("Parse failed to complete", *(results.first)); - //throw ParserError("Parse failed to complete at: " + (*(results.first))->text , *(results.first)); - } - } - dispatchkit::Boxed_Value evaluate_string(const std::string &input, const char *filename = "__EVAL__") { - using namespace langkit; - std::vector tokens = lexer.lex(input, filename); - dispatchkit::Boxed_Value value; + void debug_print(langkit::TokenPtr token, std::string prepend) { + using namespace langkit; + std::cout << prepend << "Token: " << token->text << "(" << tokentype_to_string(token->identifier) << ") @ " << token->filename + << ": (" << token->start.line << ", " << token->start.column << ") to (" + << token->end.line << ", " << token->end.column << ") " << std::endl; - for (unsigned int i = 0; i < tokens.size(); ++i) { - if ((tokens[i]->identifier == TokenType::Quoted_String) || (tokens[i]->identifier == TokenType::Single_Quoted_String)) { - tokens[i]->text = tokens[i]->text.substr(1, tokens[i]->text.size()-2); + for (unsigned int i = 0; i < token->children.size(); ++i) { + debug_print(token->children[i], prepend + " "); } } - //debug_print(tokens); - try { - TokenPtr parent = parse(parser, tokens, filename); - value = eval_token(engine, parent); + void debug_print(std::vector &tokens) { + using namespace langkit; + for (unsigned int i = 0; i < tokens.size(); ++i) { + debug_print(tokens[i], ""); + } } - catch (const ReturnValue &rv) { - value = rv.retval; + + langkit::Lexer build_lexer() { + using namespace langkit; + Lexer lexer; + lexer.set_skip(Pattern("[ \\t]+", TokenType::Whitespace)); + lexer.set_line_sep(Pattern("\\n|\\r\\n", TokenType::Carriage_Return)); + lexer.set_command_sep(Pattern(";|\\r\\n|\\n", TokenType::Semicolon)); + lexer.set_multiline_comment(Pattern("/\\*", TokenType::Comment), Pattern("\\*/", TokenType::Comment)); + lexer.set_singleline_comment(Pattern("//", TokenType::Comment)); + + lexer << Pattern("[A-Za-z_][A-Za-z_0-9]*", TokenType::Identifier); + lexer << Pattern("[0-9]+\\.[0-9]+", TokenType::Real_Number); + lexer << Pattern("[0-9]+", TokenType::Integer); + lexer << Pattern("[!@#$%^&*|\\-+=<>.]+|/[!@#$%^&|\\-+=<>]*", TokenType::Operator); + lexer << Pattern("\\(", TokenType::Parens_Open); + lexer << Pattern("\\)", TokenType::Parens_Close); + lexer << Pattern("\\[", TokenType::Square_Open); + lexer << Pattern("\\]", TokenType::Square_Close); + lexer << Pattern("\\{", TokenType::Curly_Open); + lexer << Pattern("\\}", TokenType::Curly_Close); + lexer << Pattern(",", TokenType::Comma); + lexer << Pattern("\"(?:[^\"\\\\]|\\\\.)*\"", TokenType::Quoted_String); + lexer << Pattern("'(?:[^'\\\\]|\\\\.)*'", TokenType::Single_Quoted_String); + + return lexer; } - catch (ParserError &pe) { - if (filename != std::string("__EVAL__")) { - std::cout << "Parsing error: \"" << pe.reason << "\" in '" << pe.location->filename << "' line: " << pe.location->start.line+1 << std::endl; + + langkit::Rule build_parser_rules() { + using namespace langkit; + Rule params; + Rule block(TokenType::Scoped_Block); + Rule fundef(TokenType::Function_Def); + Rule lambda_def(TokenType::Lambda_Def); + Rule statement; + Rule equation(TokenType::Equation); + Rule boolean(TokenType::Boolean); + Rule comparison(TokenType::Comparison); + Rule expression(TokenType::Expression); + Rule term(TokenType::Term); + Rule factor(TokenType::Factor); + Rule negate(TokenType::Negate); + Rule boolean_not(TokenType::Not); + Rule prefix(TokenType::Prefix); + + Rule funcall(TokenType::Fun_Call); + Rule methodcall(TokenType::Method_Call); + Rule if_block(TokenType::If_Block); + Rule while_block(TokenType::While_Block); + Rule for_block(TokenType::For_Block); + Rule arraycall(TokenType::Array_Call); + Rule vardecl(TokenType::Variable_Decl); + Rule arrayinit(TokenType::Array_Init); + + Rule return_statement(TokenType::Return); + Rule break_statement(TokenType::Break); + + Rule value; + Rule statements; + Rule for_conditions; + Rule source_elem; + Rule source_elems; + Rule statement_list; + Rule paren_block; + + Rule rule = *(Ign(Id(TokenType::Semicolon))) >> source_elems >> *(Ign(Id(TokenType::Semicolon))); + + source_elems = source_elem >> *(+Ign(Id(TokenType::Semicolon)) >> source_elem); + source_elem = fundef | statement; + statement_list = statement >> *(+Ign(Id(TokenType::Semicolon)) >> statement); + statement = if_block | while_block | for_block | equation; + + if_block = Ign(Str("if")) >> boolean >> block >> *(*Ign(Id(TokenType::Semicolon)) >> Str("elseif") >> boolean >> block) >> ~(*Ign(Id(TokenType::Semicolon)) >> Str("else") >> block); + while_block = Ign(Str("while")) >> boolean >> block; + for_block = Ign(Str("for")) >> for_conditions >> block; + for_conditions = Ign(Id(TokenType::Parens_Open)) >> ~equation >> Ign(Str(";")) >> boolean >> Ign(Str(";")) >> equation >> Ign(Id(TokenType::Parens_Close)); + + fundef = Ign(Str("def")) >> Id(TokenType::Identifier) >> ~(Ign(Id(TokenType::Parens_Open)) >> ~params >> Ign(Id(TokenType::Parens_Close))) >> + block; + params = Id(TokenType::Identifier) >> *(Ign(Str(",")) >> Id(TokenType::Identifier)); + block = *(Ign(Id(TokenType::Semicolon))) >> Ign(Id(TokenType::Curly_Open)) >> *(Ign(Id(TokenType::Semicolon))) >> ~statement_list >> *(Ign(Id(TokenType::Semicolon))) >> Ign(Id(TokenType::Curly_Close)); + + equation = *(((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("=")) | + ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("+=")) | + ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("-=")) | + ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("*=")) | + ((vardecl | arraycall | Id(TokenType::Identifier)) >> Str("/="))) >> boolean; + boolean = comparison >> *((Str("&&") >> comparison) | (Str("||") >> comparison)); + comparison = expression >> *((Str("==") >> expression) | (Str("!=") >> expression) | (Str("<") >> expression) | + (Str("<=") >> expression) |(Str(">") >> expression) | (Str(">=") >> expression)); + expression = term >> *((Str("+") >> term) | (Str("-") >> term)); + term = factor >> *((Str("*") >> factor) | (Str("/") >> factor)); + factor = methodcall | arraycall | value | negate | boolean_not | prefix | (Ign(Str("+")) >> value); + value = vardecl | arrayinit | block | paren_block | lambda_def | return_statement | break_statement | + funcall | Id(TokenType::Identifier) | Id(TokenType::Real_Number) | Id(TokenType::Integer) | Id(TokenType::Quoted_String) | + Id(TokenType::Single_Quoted_String) ; + + funcall = Id(TokenType::Identifier) >> Ign(Id(TokenType::Parens_Open)) >> ~(boolean >> *(Ign(Str("," )) >> boolean)) >> Ign(Id(TokenType::Parens_Close)); + methodcall = value >> +(Ign(Str(".")) >> funcall); + negate = (Str("-") >> (boolean | arraycall)); + boolean_not = (Str("!") >> (boolean | arraycall)); + prefix = (Str("++") >> (boolean | arraycall)) | (Str("--") >> (boolean | arraycall)); + arraycall = value >> +((Ign(Id(TokenType::Square_Open)) >> boolean >> Ign(Id(TokenType::Square_Close)))); + + arrayinit = Ign(Id(TokenType::Square_Open)) >> ~(boolean >> *(Ign(Str(",")) >> boolean)) >> Ign(Id(TokenType::Square_Close)); + vardecl = Ign(Str("var")) >> Id(TokenType::Identifier); + return_statement = Ign(Str("return")) >> ~boolean; + break_statement = Wrap(Ign(Str("break"))); + paren_block = (Ign(Id(TokenType::Parens_Open)) >> equation >> Ign(Id(TokenType::Parens_Close))); + lambda_def = Ign(Str("function")) >> ~(Ign(Id(TokenType::Parens_Open)) >> ~params >> Ign(Id(TokenType::Parens_Close))) >> block; + + return rule; + } + + + Eval_Engine build_eval_system(langkit::Lexer &lexer, langkit::Rule &parser) { + using namespace langkit; + Eval_Engine ss; + dispatchkit::Bootstrap::bootstrap(ss); + dispatchkit::bootstrap_vector >(ss, "Vector"); + + ss.register_function(boost::shared_ptr( + new dispatchkit::Dynamic_Proxy_Function(boost::bind(&ChaiScript_System::eval, boost::ref(*this), _1), 1)), "eval"); + + evaluate_string("def print(x) { print_string(x.to_string()) } "); + + return ss; + } + + langkit::TokenPtr parse(langkit::Rule &rule, std::vector &tokens, const char *filename) { + using namespace langkit; + + Token_Iterator iter = tokens.begin(), end = tokens.end(); + TokenPtr parent(new Token("Root", TokenType::File, filename)); + + std::pair results = rule(iter, end, parent); + + if ((results.second) && (results.first == end)) { + //debug_print(parent, ""); + return parent; } else { - std::cout << "Parsing error: \"" << pe.reason << "\"" << std::endl; + throw ParserError("Parse failed to complete", *(results.first)); + //throw ParserError("Parse failed to complete at: " + (*(results.first))->text , *(results.first)); } } - catch (EvalError &ee) { - if (filename != std::string("__EVAL__")) { - std::cout << "Eval error: \"" << ee.reason << "\" in '" << ee.location->filename << "' line: " << ee.location->start.line+1 << std::endl; + + dispatchkit::Boxed_Value evaluate_string(const std::string &input, const char *filename = "__EVAL__") { + using namespace langkit; + std::vector tokens = lexer.lex(input, filename); + dispatchkit::Boxed_Value value; + + for (unsigned int i = 0; i < tokens.size(); ++i) { + if ((tokens[i]->identifier == TokenType::Quoted_String) || (tokens[i]->identifier == TokenType::Single_Quoted_String)) { + tokens[i]->text = tokens[i]->text.substr(1, tokens[i]->text.size()-2); + } } - else { - std::cout << "Eval error: \"" << ee.reason << "\"" << std::endl; + + //debug_print(tokens); + try { + TokenPtr parent = parse(parser, tokens, filename); + value = eval_token(engine, parent); } - } - catch (std::exception &e) { - std::cout << "Exception: " << e.what() << std::endl; + catch (const ReturnValue &rv) { + value = rv.retval; + } + catch (ParserError &pe) { + if (filename != std::string("__EVAL__")) { + std::cout << "Parsing error: \"" << pe.reason << "\" in '" << pe.location->filename << "' line: " << pe.location->start.line+1 << std::endl; + } + else { + std::cout << "Parsing error: \"" << pe.reason << "\"" << std::endl; + } + } + catch (EvalError &ee) { + if (filename != std::string("__EVAL__")) { + std::cout << "Eval error: \"" << ee.reason << "\" in '" << ee.location->filename << "' line: " << ee.location->start.line+1 << std::endl; + } + else { + std::cout << "Eval error: \"" << ee.reason << "\"" << std::endl; + } + } + catch (std::exception &e) { + std::cout << "Exception: " << e.what() << std::endl; + } + + return value; } - return value; - } - - dispatchkit::Boxed_Value evaluate_file(const char *filename) { - return evaluate_string(load_file(filename), filename); - } -}; - -typedef ChaiScript_System ChaiScript_Engine; + dispatchkit::Boxed_Value evaluate_file(const char *filename) { + return evaluate_string(load_file(filename), filename); + } + }; + typedef ChaiScript_System ChaiScript_Engine; +} #endif /* CHAISCRIPT_ENGINE_HPP_ */ diff --git a/chaiscript/chaiscript_eval.hpp b/chaiscript/chaiscript_eval.hpp index 0ff63e0..b03e88f 100644 --- a/chaiscript/chaiscript_eval.hpp +++ b/chaiscript/chaiscript_eval.hpp @@ -6,445 +6,447 @@ #include -struct ParserError { - std::string reason; - langkit::TokenPtr location; +namespace chaiscript +{ + struct ParserError { + std::string reason; + langkit::TokenPtr location; - ParserError(const std::string &why, const langkit::TokenPtr where) : reason(why), location(where){ } -}; + ParserError(const std::string &why, const langkit::TokenPtr where) : reason(why), location(where){ } + }; -struct EvalError { - std::string reason; - langkit::TokenPtr location; + struct EvalError { + std::string reason; + langkit::TokenPtr location; - EvalError(const std::string &why, const langkit::TokenPtr where) : reason(why), location(where) { } -}; + EvalError(const std::string &why, const langkit::TokenPtr where) : reason(why), location(where) { } + }; -struct ReturnValue { - dispatchkit::Boxed_Value retval; - langkit::TokenPtr location; + struct ReturnValue { + dispatchkit::Boxed_Value retval; + langkit::TokenPtr location; - ReturnValue(const dispatchkit::Boxed_Value &return_value, const langkit::TokenPtr where) : retval(return_value), location(where) { } -}; + ReturnValue(const dispatchkit::Boxed_Value &return_value, const langkit::TokenPtr where) : retval(return_value), location(where) { } + }; -struct BreakLoop { - langkit::TokenPtr location; + struct BreakLoop { + langkit::TokenPtr location; - BreakLoop(const langkit::TokenPtr where) : location(where) { } -}; + BreakLoop(const langkit::TokenPtr where) : location(where) { } + }; -template -const dispatchkit::Boxed_Value eval_function (Eval_System &ss, langkit::TokenPtr node, const std::vector ¶m_names, const std::vector &vals) { - ss.new_scope(); + template + const dispatchkit::Boxed_Value eval_function (Eval_System &ss, langkit::TokenPtr node, const std::vector ¶m_names, const std::vector &vals) { + ss.new_scope(); - for (unsigned int i = 0; i < param_names.size(); ++i) { - ss.add_object(param_names[i], vals[i]); + for (unsigned int i = 0; i < param_names.size(); ++i) { + ss.add_object(param_names[i], vals[i]); + } + + dispatchkit::Boxed_Value retval = eval_token(ss, node); + ss.pop_scope(); + return retval; } - dispatchkit::Boxed_Value retval = eval_token(ss, node); - ss.pop_scope(); - return retval; -} + template + dispatchkit::Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { + dispatchkit::Boxed_Value retval; + unsigned int i, j; -template -dispatchkit::Boxed_Value eval_token(Eval_System &ss, langkit::TokenPtr node) { - dispatchkit::Boxed_Value retval; - unsigned int i, j; - - switch (node->identifier) { - case (TokenType::Value) : - case (TokenType::File) : - for (i = 0; i < node->children.size(); ++i) { - retval = eval_token(ss, node->children[i]); - } - break; - case (TokenType::Identifier) : - if (node->text == "true") { - retval = dispatchkit::Boxed_Value(true); - } - else if (node->text == "false") { - retval = dispatchkit::Boxed_Value(false); - } - else { - try { - retval = ss.get_object(node->text); - } - catch (std::exception &e) { - throw EvalError("Can not find object: " + node->text, node); - } - } - break; - case (TokenType::Real_Number) : - retval = dispatchkit::Boxed_Value(double(atof(node->text.c_str()))); - break; - case (TokenType::Integer) : - retval = dispatchkit::Boxed_Value(atoi(node->text.c_str())); - break; - case (TokenType::Quoted_String) : - retval = dispatchkit::Boxed_Value(node->text); - break; - case (TokenType::Single_Quoted_String) : - retval = dispatchkit::Boxed_Value(node->text); - break; - case (TokenType::Equation) : - retval = eval_token(ss, node->children.back()); - if (node->children.size() > 1) { - for (i = node->children.size()-3; ((int)i) >= 0; i -= 2) { - dispatchkit::Param_List_Builder plb; - plb << eval_token(ss, node->children[i]); - plb << retval; - try { - retval = dispatch(ss.get_function(node->children[i+1]->text), plb); - } - catch(std::exception &e){ - throw EvalError("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]); - } - } - } - break; - case (TokenType::Variable_Decl): { - ss.add_object(node->children[0]->text, dispatchkit::Boxed_Value()); - retval = ss.get_object(node->children[0]->text); - } - break; - case (TokenType::Factor) : - case (TokenType::Expression) : - case (TokenType::Term) : - case (TokenType::Boolean) : - case (TokenType::Comparison) : { - retval = eval_token(ss, node->children[0]); - if (node->children.size() > 1) { - for (i = 1; i < node->children.size(); i += 2) { - dispatchkit::Param_List_Builder plb; - plb << retval; - plb << eval_token(ss, node->children[i + 1]); - - try { - retval = dispatch(ss.get_function(node->children[i]->text), plb); - } - catch(std::exception &e){ - throw EvalError("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]); - } - } - } - } - break; - case (TokenType::Array_Call) : { - retval = eval_token(ss, node->children[0]); - for (i = 1; i < node->children.size(); ++i) { - dispatchkit::Param_List_Builder plb; - plb << retval; - plb << eval_token(ss, node->children[i]); - try { - retval = dispatch(ss.get_function("[]"), plb); - } - catch(std::out_of_range &oor) { - throw EvalError("Out of bounds exception", node); - } - catch(std::exception &e){ - throw EvalError("Can not find appropriate array lookup '[]'", node->children[i]); - } - } - } - break; - case (TokenType::Negate) : { - retval = eval_token(ss, node->children[1]); - dispatchkit::Param_List_Builder plb; - plb << retval; - plb << dispatchkit::Boxed_Value(-1); - - try { - retval = dispatch(ss.get_function("*"), plb); - } - catch(std::exception &e){ - throw EvalError("Can not find appropriate negation", node->children[0]); - } - } - break; - case (TokenType::Not) : { - bool cond; - try { - retval = eval_token(ss, node->children[1]); - cond = dispatchkit::Cast_Helper()(retval); - } - catch (std::exception) { - throw EvalError("Boolean not('!') condition not boolean", node->children[0]); - } - retval = dispatchkit::Boxed_Value(!cond); - } - break; - case (TokenType::Prefix) : { - retval = eval_token(ss, node->children[1]); - dispatchkit::Param_List_Builder plb; - plb << retval; - - try { - retval = dispatch(ss.get_function(node->children[0]->text), plb); - } - catch(std::exception &e){ - throw EvalError("Can not find appropriate prefix", node->children[0]); - } - } - break; - case (TokenType::Array_Init) : { - try { - retval = dispatch(ss.get_function("Vector"), dispatchkit::Param_List_Builder()); + switch (node->identifier) { + case (TokenType::Value) : + case (TokenType::File) : for (i = 0; i < node->children.size(); ++i) { + retval = eval_token(ss, node->children[i]); + } + break; + case (TokenType::Identifier) : + if (node->text == "true") { + retval = dispatchkit::Boxed_Value(true); + } + else if (node->text == "false") { + retval = dispatchkit::Boxed_Value(false); + } + else { try { - dispatchkit::Boxed_Value tmp = eval_token(ss, node->children[i]); - dispatch(ss.get_function("push_back"), dispatchkit::Param_List_Builder() << retval << tmp); + retval = ss.get_object(node->text); } - catch (std::exception inner_e) { - throw EvalError("Can not find appropriate 'push_back'", node->children[i]); + catch (std::exception &e) { + throw EvalError("Can not find object: " + node->text, node); + } + } + break; + case (TokenType::Real_Number) : + retval = dispatchkit::Boxed_Value(double(atof(node->text.c_str()))); + break; + case (TokenType::Integer) : + retval = dispatchkit::Boxed_Value(atoi(node->text.c_str())); + break; + case (TokenType::Quoted_String) : + retval = dispatchkit::Boxed_Value(node->text); + break; + case (TokenType::Single_Quoted_String) : + retval = dispatchkit::Boxed_Value(node->text); + break; + case (TokenType::Equation) : + retval = eval_token(ss, node->children.back()); + if (node->children.size() > 1) { + for (i = node->children.size()-3; ((int)i) >= 0; i -= 2) { + dispatchkit::Param_List_Builder plb; + plb << eval_token(ss, node->children[i]); + plb << retval; + try { + retval = dispatch(ss.get_function(node->children[i+1]->text), plb); + } + catch(std::exception &e){ + throw EvalError("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]); + } + } + } + break; + case (TokenType::Variable_Decl): { + ss.add_object(node->children[0]->text, dispatchkit::Boxed_Value()); + retval = ss.get_object(node->children[0]->text); + } + break; + case (TokenType::Factor) : + case (TokenType::Expression) : + case (TokenType::Term) : + case (TokenType::Boolean) : + case (TokenType::Comparison) : { + retval = eval_token(ss, node->children[0]); + if (node->children.size() > 1) { + for (i = 1; i < node->children.size(); i += 2) { + dispatchkit::Param_List_Builder plb; + plb << retval; + plb << eval_token(ss, node->children[i + 1]); + + try { + retval = dispatch(ss.get_function(node->children[i]->text), plb); + } + catch(std::exception &e){ + throw EvalError("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]); + } } } } - catch (std::exception e) { - throw EvalError("Can not find appropriate 'Vector()'", node); - } - } - break; - case (TokenType::Fun_Call) : { - - std::vector > fn; - dispatchkit::Dispatch_Engine::Stack prev_stack = ss.get_stack(); - - dispatchkit::Dispatch_Engine::Stack new_stack; - new_stack.push_back(dispatchkit::Dispatch_Engine::Scope()); - - dispatchkit::Param_List_Builder plb; - for (i = 1; i < node->children.size(); ++i) { - plb << eval_token(ss, node->children[i]); - } - try { - fn = ss.get_function(node->children[0]->text); - ss.set_stack(new_stack); - retval = dispatch(fn, plb); - ss.set_stack(prev_stack); - } - catch(EvalError &ee) { - ss.set_stack(prev_stack); - throw EvalError(ee.reason, node->children[0]); - } - catch(std::exception &e){ - ss.set_stack(prev_stack); - throw EvalError("Engine error: " + std::string(e.what()) + " on '" + node->children[0]->text + "'", node->children[0]); - } - catch(ReturnValue &rv) { - ss.set_stack(prev_stack); - retval = rv.retval; - } - } - break; - case (TokenType::Method_Call) : { - std::vector > fn; - dispatchkit::Dispatch_Engine::Stack prev_stack = ss.get_stack(); - - dispatchkit::Dispatch_Engine::Stack new_stack; - new_stack.push_back(dispatchkit::Dispatch_Engine::Scope()); - - retval = eval_token(ss, node->children[0]); - if (node->children.size() > 1) { + break; + case (TokenType::Array_Call) : { + retval = eval_token(ss, node->children[0]); for (i = 1; i < node->children.size(); ++i) { dispatchkit::Param_List_Builder plb; plb << retval; - - for (j = 1; j < node->children[i]->children.size(); ++j) { - plb << eval_token(ss, node->children[i]->children[j]); - } - + plb << eval_token(ss, node->children[i]); try { - fn = ss.get_function(node->children[i]->children[0]->text); - ss.set_stack(new_stack); - retval = dispatch(fn, plb); - ss.set_stack(prev_stack); + retval = dispatch(ss.get_function("[]"), plb); } - catch(EvalError &ee) { - ss.set_stack(prev_stack); - throw EvalError(ee.reason, node->children[0]); + catch(std::out_of_range &oor) { + throw EvalError("Out of bounds exception", node); } catch(std::exception &e){ - ss.set_stack(prev_stack); - throw EvalError("Can not find appropriate '" + node->children[i]->children[0]->text + "'", node->children[0]); - } - catch(ReturnValue &rv) { - ss.set_stack(prev_stack); - retval = rv.retval; + throw EvalError("Can not find appropriate array lookup '[]'", node->children[i]); } } } - } - break; - case(TokenType::If_Block) : { - retval = eval_token(ss, node->children[0]); - bool cond; - try { - cond = dispatchkit::Cast_Helper()(retval); - } - catch (std::exception &e) { - throw EvalError("If condition not boolean", node->children[0]); - } - if (cond) { + break; + case (TokenType::Negate) : { retval = eval_token(ss, node->children[1]); - } - else { - if (node->children.size() > 2) { - i = 2; - while ((!cond) && (i < node->children.size())) { - if (node->children[i]->text == "else") { - retval = eval_token(ss, node->children[i+1]); - cond = true; - } - else if (node->children[i]->text == "elseif") { - retval = eval_token(ss, node->children[i+1]); - try { - cond = dispatchkit::Cast_Helper()(retval); - } - catch (std::exception &e) { - throw EvalError("Elseif condition not boolean", node->children[i+1]); - } - if (cond) { - retval = eval_token(ss, node->children[i+2]); - } - } - i = i + 3; - } - } - } - } - break; - case(TokenType::While_Block) : { - retval = eval_token(ss, node->children[0]); - bool cond; - try { - cond = dispatchkit::Cast_Helper()(retval); - } - catch (std::exception) { - throw EvalError("While condition not boolean", node->children[0]); - } - while (cond) { - try { - eval_token(ss, node->children[1]); - retval = eval_token(ss, node->children[0]); - try { - cond = dispatchkit::Cast_Helper()(retval); - } - catch (std::exception) { - throw EvalError("While condition not boolean", node->children[0]); - } - } - catch (BreakLoop &bl) { - cond = false; - } - } - retval = dispatchkit::Boxed_Value(); - } - break; - case(TokenType::For_Block) : { - dispatchkit::Boxed_Value condition; - bool cond; + dispatchkit::Param_List_Builder plb; + plb << retval; + plb << dispatchkit::Boxed_Value(-1); - try { - if (node->children.size() == 4) { - eval_token(ss, node->children[0]); - condition = eval_token(ss, node->children[1]); + try { + retval = dispatch(ss.get_function("*"), plb); } - else if (node->children.size() == 3){ - condition = eval_token(ss, node->children[0]); + catch(std::exception &e){ + throw EvalError("Can not find appropriate negation", node->children[0]); } - cond = dispatchkit::Cast_Helper()(condition); } - catch (std::exception &e) { - throw EvalError("For condition not boolean", node); + break; + case (TokenType::Not) : { + bool cond; + try { + retval = eval_token(ss, node->children[1]); + cond = dispatchkit::Cast_Helper()(retval); + } + catch (std::exception) { + throw EvalError("Boolean not('!') condition not boolean", node->children[0]); + } + retval = dispatchkit::Boxed_Value(!cond); } - while (cond) { + break; + case (TokenType::Prefix) : { + retval = eval_token(ss, node->children[1]); + dispatchkit::Param_List_Builder plb; + plb << retval; + + try { + retval = dispatch(ss.get_function(node->children[0]->text), plb); + } + catch(std::exception &e){ + throw EvalError("Can not find appropriate prefix", node->children[0]); + } + } + break; + case (TokenType::Array_Init) : { + try { + retval = dispatch(ss.get_function("Vector"), dispatchkit::Param_List_Builder()); + for (i = 0; i < node->children.size(); ++i) { + try { + dispatchkit::Boxed_Value tmp = eval_token(ss, node->children[i]); + dispatch(ss.get_function("push_back"), dispatchkit::Param_List_Builder() << retval << tmp); + } + catch (std::exception inner_e) { + throw EvalError("Can not find appropriate 'push_back'", node->children[i]); + } + } + } + catch (std::exception e) { + throw EvalError("Can not find appropriate 'Vector()'", node); + } + } + break; + case (TokenType::Fun_Call) : { + + std::vector > fn; + dispatchkit::Dispatch_Engine::Stack prev_stack = ss.get_stack(); + + dispatchkit::Dispatch_Engine::Stack new_stack; + new_stack.push_back(dispatchkit::Dispatch_Engine::Scope()); + + dispatchkit::Param_List_Builder plb; + for (i = 1; i < node->children.size(); ++i) { + plb << eval_token(ss, node->children[i]); + } + try { + fn = ss.get_function(node->children[0]->text); + ss.set_stack(new_stack); + retval = dispatch(fn, plb); + ss.set_stack(prev_stack); + } + catch(EvalError &ee) { + ss.set_stack(prev_stack); + throw EvalError(ee.reason, node->children[0]); + } + catch(std::exception &e){ + ss.set_stack(prev_stack); + throw EvalError("Engine error: " + std::string(e.what()) + " on '" + node->children[0]->text + "'", node->children[0]); + } + catch(ReturnValue &rv) { + ss.set_stack(prev_stack); + retval = rv.retval; + } + } + break; + case (TokenType::Method_Call) : { + std::vector > fn; + dispatchkit::Dispatch_Engine::Stack prev_stack = ss.get_stack(); + + dispatchkit::Dispatch_Engine::Stack new_stack; + new_stack.push_back(dispatchkit::Dispatch_Engine::Scope()); + + retval = eval_token(ss, node->children[0]); + if (node->children.size() > 1) { + for (i = 1; i < node->children.size(); ++i) { + dispatchkit::Param_List_Builder plb; + plb << retval; + + for (j = 1; j < node->children[i]->children.size(); ++j) { + plb << eval_token(ss, node->children[i]->children[j]); + } + + try { + fn = ss.get_function(node->children[i]->children[0]->text); + ss.set_stack(new_stack); + retval = dispatch(fn, plb); + ss.set_stack(prev_stack); + } + catch(EvalError &ee) { + ss.set_stack(prev_stack); + throw EvalError(ee.reason, node->children[0]); + } + catch(std::exception &e){ + ss.set_stack(prev_stack); + throw EvalError("Can not find appropriate '" + node->children[i]->children[0]->text + "'", node->children[0]); + } + catch(ReturnValue &rv) { + ss.set_stack(prev_stack); + retval = rv.retval; + } + } + } + } + break; + case(TokenType::If_Block) : { + retval = eval_token(ss, node->children[0]); + bool cond; + try { + cond = dispatchkit::Cast_Helper()(retval); + } + catch (std::exception &e) { + throw EvalError("If condition not boolean", node->children[0]); + } + if (cond) { + retval = eval_token(ss, node->children[1]); + } + else { + if (node->children.size() > 2) { + i = 2; + while ((!cond) && (i < node->children.size())) { + if (node->children[i]->text == "else") { + retval = eval_token(ss, node->children[i+1]); + cond = true; + } + else if (node->children[i]->text == "elseif") { + retval = eval_token(ss, node->children[i+1]); + try { + cond = dispatchkit::Cast_Helper()(retval); + } + catch (std::exception &e) { + throw EvalError("Elseif condition not boolean", node->children[i+1]); + } + if (cond) { + retval = eval_token(ss, node->children[i+2]); + } + } + i = i + 3; + } + } + } + } + break; + case(TokenType::While_Block) : { + retval = eval_token(ss, node->children[0]); + bool cond; + try { + cond = dispatchkit::Cast_Helper()(retval); + } + catch (std::exception) { + throw EvalError("While condition not boolean", node->children[0]); + } + while (cond) { + try { + eval_token(ss, node->children[1]); + retval = eval_token(ss, node->children[0]); + try { + cond = dispatchkit::Cast_Helper()(retval); + } + catch (std::exception) { + throw EvalError("While condition not boolean", node->children[0]); + } + } + catch (BreakLoop &bl) { + cond = false; + } + } + retval = dispatchkit::Boxed_Value(); + } + break; + case(TokenType::For_Block) : { + dispatchkit::Boxed_Value condition; + bool cond; + try { if (node->children.size() == 4) { - eval_token(ss, node->children[3]); - eval_token(ss, node->children[2]); + eval_token(ss, node->children[0]); condition = eval_token(ss, node->children[1]); } - else if (node->children.size() == 3) { - eval_token(ss, node->children[2]); - eval_token(ss, node->children[1]); + else if (node->children.size() == 3){ condition = eval_token(ss, node->children[0]); } cond = dispatchkit::Cast_Helper()(condition); - } catch (std::exception &e) { throw EvalError("For condition not boolean", node); } - catch (BreakLoop &bl) { - cond = false; + while (cond) { + try { + if (node->children.size() == 4) { + eval_token(ss, node->children[3]); + eval_token(ss, node->children[2]); + condition = eval_token(ss, node->children[1]); + } + else if (node->children.size() == 3) { + eval_token(ss, node->children[2]); + eval_token(ss, node->children[1]); + condition = eval_token(ss, node->children[0]); + } + cond = dispatchkit::Cast_Helper()(condition); + + } + catch (std::exception &e) { + throw EvalError("For condition not boolean", node); + } + catch (BreakLoop &bl) { + cond = false; + } } - } - retval = dispatchkit::Boxed_Value(); - } - break; - case (TokenType::Function_Def) : { - unsigned int num_args = node->children.size() - 2; - std::vector param_names; - for (i = 0; i < num_args; ++i) { - param_names.push_back(node->children[i+1]->text); - } - - ss.register_function(boost::shared_ptr( - new dispatchkit::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(ss), node->children.back(), param_names, _1))), node->children[0]->text); - } - break; - case (TokenType::Lambda_Def) : { - unsigned int num_args = node->children.size() - 1; - std::vector param_names; - for (i = 0; i < num_args; ++i) { - param_names.push_back(node->children[i]->text); - } - - //retval = boost::shared_ptr(new dispatchkit::Proxy_Function_Impl >(&test)); - retval = dispatchkit::Boxed_Value(boost::shared_ptr( - new dispatchkit::Dynamic_Proxy_Function( - boost::bind(&eval_function, boost::ref(ss), node->children.back(), param_names, _1)))); - } - break; - case (TokenType::Scoped_Block) : { - ss.new_scope(); - for (i = 0; i < node->children.size(); ++i) { - retval = eval_token(ss, node->children[i]); - } - ss.pop_scope(); - } - break; - case (TokenType::Return) : { - if (node->children.size() > 0) { - retval = eval_token(ss, node->children[0]); - } - else { retval = dispatchkit::Boxed_Value(); } - throw ReturnValue(retval, node); + break; + case (TokenType::Function_Def) : { + unsigned int num_args = node->children.size() - 2; + std::vector param_names; + for (i = 0; i < num_args; ++i) { + param_names.push_back(node->children[i+1]->text); + } + + ss.register_function(boost::shared_ptr( + new dispatchkit::Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(ss), node->children.back(), param_names, _1))), node->children[0]->text); + } + break; + case (TokenType::Lambda_Def) : { + unsigned int num_args = node->children.size() - 1; + std::vector param_names; + for (i = 0; i < num_args; ++i) { + param_names.push_back(node->children[i]->text); + } + + //retval = boost::shared_ptr(new dispatchkit::Proxy_Function_Impl >(&test)); + retval = dispatchkit::Boxed_Value(boost::shared_ptr( + new dispatchkit::Dynamic_Proxy_Function( + boost::bind(&eval_function, boost::ref(ss), node->children.back(), param_names, _1)))); + } + break; + case (TokenType::Scoped_Block) : { + ss.new_scope(); + for (i = 0; i < node->children.size(); ++i) { + retval = eval_token(ss, node->children[i]); + } + ss.pop_scope(); + } + break; + case (TokenType::Return) : { + if (node->children.size() > 0) { + retval = eval_token(ss, node->children[0]); + } + else { + retval = dispatchkit::Boxed_Value(); + } + throw ReturnValue(retval, node); + } + break; + case (TokenType::Break) : { + throw BreakLoop(node); + } + break; + case (TokenType::Statement) : + case (TokenType::Carriage_Return) : + case (TokenType::Semicolon) : + case (TokenType::Comment) : + case (TokenType::Operator) : + case (TokenType::Whitespace) : + case (TokenType::Parens_Open) : + case (TokenType::Parens_Close) : + case (TokenType::Square_Open) : + case (TokenType::Square_Close) : + case (TokenType::Curly_Open) : + case (TokenType::Curly_Close) : + case (TokenType::Comma) : + break; } - break; - case (TokenType::Break) : { - throw BreakLoop(node); - } - break; - case (TokenType::Statement) : - case (TokenType::Carriage_Return) : - case (TokenType::Semicolon) : - case (TokenType::Comment) : - case (TokenType::Operator) : - case (TokenType::Whitespace) : - case (TokenType::Parens_Open) : - case (TokenType::Parens_Close) : - case (TokenType::Square_Open) : - case (TokenType::Square_Close) : - case (TokenType::Curly_Open) : - case (TokenType::Curly_Close) : - case (TokenType::Comma) : - break; + + return retval; } - - return retval; } - #endif /* CHAISCRIPT_EVAL_HPP_ */ diff --git a/chaiscript/main.cpp b/chaiscript/main.cpp index f935b1b..9b99a85 100644 --- a/chaiscript/main.cpp +++ b/chaiscript/main.cpp @@ -3,25 +3,27 @@ #include "chaiscript.hpp" int main(int argc, char *argv[]) { - using namespace dispatchkit; std::string input; - ChaiScript_Engine chai; + chaiscript::ChaiScript_Engine chai; if (argc < 2) { std::cout << "eval> "; std::getline(std::cin, input); while (input != "quit") { - Boxed_Value val; + dispatchkit::Boxed_Value val; val = chai.evaluate_string(input); if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) { try { - Boxed_Value printeval = dispatch(chai.get_eval_engine().get_function("to_string"), Param_List_Builder() << val); + dispatchkit::Boxed_Value printeval + = dispatchkit::dispatch(chai.get_eval_engine().get_function("to_string"), + dispatchkit::Param_List_Builder() << val); std::cout << "result: "; - dispatch(chai.get_eval_engine().get_function("print"), Param_List_Builder() << printeval); + 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 << std::endl; } @@ -33,7 +35,7 @@ int main(int argc, char *argv[]) { else { for (int i = 1; i < argc; ++i) { try { - Boxed_Value val = chai.evaluate_file(argv[i]); + dispatchkit::Boxed_Value val = chai.evaluate_file(argv[i]); } catch (std::exception &e) { std::cerr << "Could not open: " << argv[i] << std::endl;