Move structure to being inheritance-based in preparation for reflection infrastructure. This technique relies on the vtable's dynamic dispatch for correct evaluation, and removes the giant switch eval style of previous revisions.

This commit is contained in:
Jonathan Turner
2010-08-08 17:18:32 +00:00
parent 3a904d9f74
commit b1e357423f
5 changed files with 1347 additions and 488 deletions

View File

@@ -7,6 +7,8 @@
#ifndef _CHAISCRIPT_COMMON_HPP #ifndef _CHAISCRIPT_COMMON_HPP
#define _CHAISCRIPT_COMMON_HPP #define _CHAISCRIPT_COMMON_HPP
#include <chaiscript/dispatchkit/dispatchkit.hpp>
namespace chaiscript namespace chaiscript
{ {
typedef ModulePtr (*Create_Module_Func)(); typedef ModulePtr (*Create_Module_Func)();
@@ -65,9 +67,6 @@ namespace chaiscript
std::vector<TokenPtr> children; std::vector<TokenPtr> children;
TokenPtr annotation; TokenPtr annotation;
Token(const std::string &token_text, int id, const char *fname) :
text(token_text), identifier(id), filename(fname), is_cached(false) { }
Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) : Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
text(token_text), identifier(id), filename(fname), is_cached(false) { text(token_text), identifier(id), filename(fname), is_cached(false) {
@@ -76,6 +75,298 @@ namespace chaiscript
end.line = end_line; end.line = end_line;
end.column = end_col; end.column = end_col;
} }
Token(const std::string &token_text, int id, const char *fname) :
text(token_text), identifier(id), filename(fname), is_cached(false) { }
void cache_const(const Boxed_Value &value) {
this->cached_value = value;
this->is_cached = true;
}
virtual Boxed_Value eval(Dispatch_Engine &) {
Boxed_Value bv;
throw std::runtime_error("Undispatched token (internal error)");
return bv;
}
};
struct Error_Token : public Token {
public:
Error_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Int_Token : public Token {
public:
Int_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Float_Token : public Token {
public:
Float_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Id_Token : public Token {
public:
Id_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Char_Token : public Token {
public:
Char_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Str_Token : public Token {
public:
Str_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Eol_Token : public Token {
public:
Eol_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Fun_Call_Token : public Token {
public:
Fun_Call_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Inplace_Fun_Call_Token : public Token {
public:
Inplace_Fun_Call_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Arg_List_Token : public Token {
public:
Arg_List_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Variable_Token : public Token {
public:
Variable_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Equation_Token : public Token {
public:
Equation_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Var_Decl_Token : public Token {
public:
Var_Decl_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Comparison_Token : public Token {
public:
Comparison_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Additive_Token : public Token {
public:
Additive_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Multiplicative_Token : public Token {
public:
Multiplicative_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Array_Call_Token : public Token {
public:
Array_Call_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Dot_Access_Token : public Token {
public:
Dot_Access_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Quoted_String_Token : public Token {
public:
Quoted_String_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Single_Quoted_String_Token : public Token {
public:
Single_Quoted_String_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Lambda_Token : public Token {
public:
Lambda_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Block_Token : public Token {
public:
Block_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Def_Token : public Token {
public:
Def_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct While_Token : public Token {
public:
While_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct If_Token : public Token {
public:
If_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct For_Token : public Token {
public:
For_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Inline_Array_Token : public Token {
public:
Inline_Array_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Inline_Map_Token : public Token {
public:
Inline_Map_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Return_Token : public Token {
public:
Return_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct File_Token : public Token {
public:
File_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Prefix_Token : public Token {
public:
Prefix_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Break_Token : public Token {
public:
Break_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Map_Pair_Token : public Token {
public:
Map_Pair_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Value_Range_Token : public Token {
public:
Value_Range_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Inline_Range_Token : public Token {
public:
Inline_Range_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Annotation_Token : public Token {
public:
Annotation_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Try_Token : public Token {
public:
Try_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Catch_Token : public Token {
public:
Catch_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Finally_Token : public Token {
public:
Finally_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
};
struct Method_Token : public Token {
public:
Method_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Attr_Decl_Token : public Token {
public:
Attr_Decl_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Shift_Token : public Token {
public:
Shift_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Equality_Token : public Token {
public:
Equality_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Bitwise_And_Token : public Token {
public:
Bitwise_And_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Bitwise_Xor_Token : public Token {
public:
Bitwise_Xor_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Bitwise_Or_Token : public Token {
public:
Bitwise_Or_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Logical_And_Token : public Token {
public:
Logical_And_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
};
struct Logical_Or_Token : public Token {
public:
Logical_Or_Token(const std::string &token_text, int id, const char *fname, int start_line, int start_col, int end_line, int end_col) :
Token(token_text, id, fname, start_line, start_col, end_line, end_col) { }
Boxed_Value eval(Dispatch_Engine &ss);
}; };
/** /**
@@ -86,6 +377,7 @@ namespace chaiscript
File_Position start_position; File_Position start_position;
File_Position end_position; File_Position end_position;
const char *filename; const char *filename;
std::vector<TokenPtr> call_stack;
Eval_Error(const std::string &why, const File_Position &where, const char *fname) : Eval_Error(const std::string &why, const File_Position &where, const char *fname) :
std::runtime_error("Error: \"" + why + "\" " + std::runtime_error("Error: \"" + why + "\" " +
@@ -95,13 +387,9 @@ namespace chaiscript
reason(why), start_position(where), end_position(where), filename(fname) reason(why), start_position(where), end_position(where), filename(fname)
{ } { }
Eval_Error(const std::string &why, const TokenPtr &where) Eval_Error(const std::string &why)
: std::runtime_error("Error: \"" + why + "\" " + : std::runtime_error("Error: \"" + why + "\" "),
(std::string(where->filename) != "__EVAL__" ? ("in '" + std::string(where->filename) + "' ") : "during evaluation ") + reason(why) {}
"at (" + boost::lexical_cast<std::string>(where->start.line) + ", " +
boost::lexical_cast<std::string>(where->start.column) + ")"),
reason(why), start_position(where->start), end_position(where->end), filename(where->filename) {
}
virtual ~Eval_Error() throw() {} virtual ~Eval_Error() throw() {}
}; };
@@ -123,18 +411,15 @@ namespace chaiscript
*/ */
struct Return_Value { struct Return_Value {
Boxed_Value retval; Boxed_Value retval;
TokenPtr location;
Return_Value(const Boxed_Value &return_value, const TokenPtr where) : retval(return_value), location(where) { } Return_Value(const Boxed_Value &return_value) : retval(return_value) { }
}; };
/** /**
* Special type indicating a call to 'break' * Special type indicating a call to 'break'
*/ */
struct Break_Loop { struct Break_Loop {
TokenPtr location; Break_Loop() { }
Break_Loop(const TokenPtr where) : location(where) { }
}; };
} }

View File

@@ -263,7 +263,7 @@ namespace chaiscript
l.unlock(); l.unlock();
#endif #endif
//parser.show_match_stack(); //parser.show_match_stack();
value = eval_token<Eval_Engine>(engine, parser.ast()); value = parser.ast()->eval(engine);//eval_token<Eval_Engine>(engine, parser.ast());
} }
} }
catch (const Return_Value &rv) { catch (const Return_Value &rv) {
@@ -281,7 +281,7 @@ namespace chaiscript
if (parser.parse(input, fname)) { if (parser.parse(input, fname)) {
//parser.show_match_stack(); //parser.show_match_stack();
value = eval_token<Eval_Engine>(engine, parser.ast()); value = parser.ast()->eval(engine);
} }
} }
catch (const Return_Value &rv) { catch (const Return_Value &rv) {

File diff suppressed because it is too large Load Diff

View File

@@ -137,17 +137,183 @@ namespace chaiscript
* Helper function that collects tokens from a starting position to the top of the stack into a new AST node * Helper function that collects tokens from a starting position to the top of the stack into a new AST node
*/ */
void build_match(Token_Type::Type match_type, int match_start) { void build_match(Token_Type::Type match_type, int match_start) {
int pos_line_start, pos_col_start, pos_line_stop, pos_col_stop;
int is_deep = false;
//so we want to take everything to the right of this and make them children //so we want to take everything to the right of this and make them children
if (match_start != int(match_stack.size())) { if (match_start != int(match_stack.size())) {
TokenPtr t(new Token("", match_type, filename, match_stack[match_start]->start.line, match_stack[match_start]->start.column, line, col)); pos_line_start = match_stack[match_start]->start.line;
pos_col_start = match_stack[match_start]->start.column;
pos_line_stop = line;
pos_col_stop = col;
is_deep = true;
}
else {
pos_line_start = line;
pos_col_start = col;
pos_line_stop = line;
pos_col_stop = col;
}
Token *t;
switch (match_type) {
case(Token_Type::Error) :
t = new Error_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Int) :
t = new Int_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Float) :
t = new Float_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Id) :
t = new Id_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Char) :
t = new Char_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Str) :
t = new Str_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Eol) :
t = new Eol_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Fun_Call) :
t = new Fun_Call_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Inplace_Fun_Call) :
t = new Inplace_Fun_Call_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Arg_List) :
t = new Arg_List_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Variable) :
t = new Variable_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Equation) :
t = new Equation_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Var_Decl) :
t = new Var_Decl_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Comparison) :
t = new Comparison_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Additive) :
t = new Additive_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Multiplicative) :
t = new Multiplicative_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Array_Call) :
t = new Array_Call_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Dot_Access) :
t = new Dot_Access_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Quoted_String) :
t = new Quoted_String_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Single_Quoted_String) :
t = new Single_Quoted_String_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Lambda) :
t = new Lambda_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Block) :
t = new Block_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Def) :
t = new Def_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::While) :
t = new While_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::If) :
t = new If_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::For) :
t = new For_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Inline_Array) :
t = new Inline_Array_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Inline_Map) :
t = new Inline_Map_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Return) :
t = new Return_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::File) :
t = new File_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Prefix) :
t = new Prefix_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Break) :
t = new Break_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Map_Pair) :
t = new Map_Pair_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Value_Range) :
t = new Value_Range_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Inline_Range) :
t = new Inline_Range_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Annotation) :
t = new Annotation_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Try) :
t = new Try_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Catch) :
t = new Catch_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Finally) :
t = new Finally_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Method) :
t = new Method_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Attr_Decl) :
t = new Attr_Decl_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Shift) :
t = new Shift_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Equality) :
t = new Equality_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Bitwise_And) :
t = new Bitwise_And_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Bitwise_Xor) :
t = new Bitwise_Xor_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Bitwise_Or) :
t = new Bitwise_Or_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Logical_And) :
t = new Logical_And_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
case(Token_Type::Logical_Or) :
t = new Logical_Or_Token("", match_type, filename, pos_line_start, pos_col_start, pos_line_stop, pos_col_stop);
break;
}
TokenPtr tp(t);
if (is_deep) {
t->children.assign(match_stack.begin() + (match_start), match_stack.end()); t->children.assign(match_stack.begin() + (match_start), match_stack.end());
match_stack.erase(match_stack.begin() + (match_start), match_stack.end()); match_stack.erase(match_stack.begin() + (match_start), match_stack.end());
match_stack.push_back(t); match_stack.push_back(tp);
} }
else { else {
//todo: fix the fact that a successful match that captured no tokens doesn't have any real start position //todo: fix the fact that a successful match that captured no tokens doesn't have any real start position
TokenPtr t(new Token("", match_type, filename, line, col, line, col)); match_stack.push_back(tp);
match_stack.push_back(t);
} }
} }
@@ -349,7 +515,7 @@ namespace chaiscript
std::ostringstream out_int; std::ostringstream out_int;
out_int << int(temp_int); out_int << int(temp_int);
TokenPtr t(new Token(out_int.str(), Token_Type::Int, filename, prev_line, prev_col, line, col)); TokenPtr t(new Int_Token(out_int.str(), Token_Type::Int, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -368,13 +534,13 @@ namespace chaiscript
std::ostringstream out_int; std::ostringstream out_int;
out_int << temp_int; out_int << temp_int;
TokenPtr t(new Token(out_int.str(), Token_Type::Int, filename, prev_line, prev_col, line, col)); TokenPtr t(new Int_Token(out_int.str(), Token_Type::Int, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
if (Float_()) { if (Float_()) {
std::string match(start, input_pos); std::string match(start, input_pos);
TokenPtr t(new Token(match, Token_Type::Float, filename, prev_line, prev_col, line, col)); TokenPtr t(new Float_Token(match, Token_Type::Float, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -387,11 +553,11 @@ namespace chaiscript
std::ostringstream out_int; std::ostringstream out_int;
out_int << int(temp_int); out_int << int(temp_int);
TokenPtr t(new Token(out_int.str(), Token_Type::Int, filename, prev_line, prev_col, line, col)); TokenPtr t(new Int_Token(out_int.str(), Token_Type::Int, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
} }
else { else {
TokenPtr t(new Token(match, Token_Type::Int, filename, prev_line, prev_col, line, col)); TokenPtr t(new Int_Token(match, Token_Type::Int, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
} }
return true; return true;
@@ -462,13 +628,13 @@ namespace chaiscript
if (*start == '`') { if (*start == '`') {
//Id Literal //Id Literal
std::string match(start+1, input_pos-1); std::string match(start+1, input_pos-1);
TokenPtr t(new Token(match, Token_Type::Id, filename, prev_line, prev_col, line, col)); TokenPtr t(new Id_Token(match, Token_Type::Id, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
else { else {
std::string match(start, input_pos); std::string match(start, input_pos);
TokenPtr t(new Token(match, Token_Type::Id, filename, prev_line, prev_col, line, col)); TokenPtr t(new Id_Token(match, Token_Type::Id, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -501,7 +667,7 @@ namespace chaiscript
} while (Symbol("#")); } while (Symbol("#"));
std::string match(start, input_pos); std::string match(start, input_pos);
TokenPtr t(new Token(match, Token_Type::Annotation, filename, prev_line, prev_col, line, col)); TokenPtr t(new Annotation_Token(match, Token_Type::Annotation, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -576,23 +742,23 @@ namespace chaiscript
if (is_interpolated) { if (is_interpolated) {
//If we've seen previous interpolation, add on instead of making a new one //If we've seen previous interpolation, add on instead of making a new one
TokenPtr plus(new Token("+", Token_Type::Str, filename, prev_line, prev_col, line, col)); TokenPtr plus(new Str_Token("+", Token_Type::Str, filename, prev_line, prev_col, line, col));
match_stack.push_back(plus); match_stack.push_back(plus);
TokenPtr t(new Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col)); TokenPtr t(new Quoted_String_Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
build_match(Token_Type::Additive, prev_stack_top); build_match(Token_Type::Additive, prev_stack_top);
} }
else { else {
TokenPtr t(new Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col)); TokenPtr t(new Quoted_String_Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
} }
//We've finished with the part of the string up to this point, so clear it //We've finished with the part of the string up to this point, so clear it
match = ""; match = "";
TokenPtr plus(new Token("+", Token_Type::Str, filename, prev_line, prev_col, line, col)); TokenPtr plus(new Str_Token("+", Token_Type::Str, filename, prev_line, prev_col, line, col));
match_stack.push_back(plus); match_stack.push_back(plus);
std::string eval_match; std::string eval_match;
@@ -608,17 +774,17 @@ namespace chaiscript
int tostr_stack_top = match_stack.size(); int tostr_stack_top = match_stack.size();
TokenPtr tostr(new Token("to_string", Token_Type::Id, filename, prev_line, prev_col, line, col)); TokenPtr tostr(new Id_Token("to_string", Token_Type::Id, filename, prev_line, prev_col, line, col));
match_stack.push_back(tostr); match_stack.push_back(tostr);
int ev_stack_top = match_stack.size(); int ev_stack_top = match_stack.size();
TokenPtr ev(new Token("eval", Token_Type::Id, filename, prev_line, prev_col, line, col)); TokenPtr ev(new Id_Token("eval", Token_Type::Id, filename, prev_line, prev_col, line, col));
match_stack.push_back(ev); match_stack.push_back(ev);
int arg_stack_top = match_stack.size(); int arg_stack_top = match_stack.size();
TokenPtr t(new Token(eval_match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col)); TokenPtr t(new Quoted_String_Token(eval_match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
build_match(Token_Type::Arg_List, arg_stack_top); build_match(Token_Type::Arg_List, arg_stack_top);
@@ -676,16 +842,16 @@ namespace chaiscript
} }
} }
if (is_interpolated) { if (is_interpolated) {
TokenPtr plus(new Token("+", Token_Type::Str, filename, prev_line, prev_col, line, col)); TokenPtr plus(new Str_Token("+", Token_Type::Str, filename, prev_line, prev_col, line, col));
match_stack.push_back(plus); match_stack.push_back(plus);
TokenPtr t(new Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col)); TokenPtr t(new Quoted_String_Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
build_match(Token_Type::Additive, prev_stack_top); build_match(Token_Type::Additive, prev_stack_top);
} }
else { else {
TokenPtr t(new Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col)); TokenPtr t(new Quoted_String_Token(match, Token_Type::Quoted_String, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
} }
return true; return true;
@@ -777,7 +943,7 @@ namespace chaiscript
is_escaped = false; is_escaped = false;
} }
} }
TokenPtr t(new Token(match, Token_Type::Single_Quoted_String, filename, prev_line, prev_col, line, col)); TokenPtr t(new Single_Quoted_String_Token(match, Token_Type::Single_Quoted_String, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -816,7 +982,7 @@ namespace chaiscript
int prev_line = line; int prev_line = line;
if (Char_(c)) { if (Char_(c)) {
std::string match(start, input_pos); std::string match(start, input_pos);
TokenPtr t(new Token(match, Token_Type::Char, filename, prev_line, prev_col, line, col)); TokenPtr t(new Char_Token(match, Token_Type::Char, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -889,7 +1055,7 @@ namespace chaiscript
return false; return false;
} }
std::string match(start, input_pos); std::string match(start, input_pos);
TokenPtr t(new Token(match, Token_Type::Str, filename, prev_line, prev_col, line, col)); TokenPtr t(new Str_Token(match, Token_Type::Str, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -967,7 +1133,7 @@ namespace chaiscript
} }
else { else {
std::string match(start, input_pos); std::string match(start, input_pos);
TokenPtr t(new Token(match, Token_Type::Str, filename, prev_line, prev_col, line, col)); TokenPtr t(new Str_Token(match, Token_Type::Str, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -1011,7 +1177,7 @@ namespace chaiscript
int prev_line = line; int prev_line = line;
if (Eol_()) { if (Eol_()) {
std::string match(start, input_pos); std::string match(start, input_pos);
TokenPtr t(new Token(match, Token_Type::Eol, filename, prev_line, prev_col, line, col)); TokenPtr t(new Eol_Token(match, Token_Type::Eol, filename, prev_line, prev_col, line, col));
match_stack.push_back(t); match_stack.push_back(t);
return true; return true;
} }
@@ -1036,7 +1202,7 @@ namespace chaiscript
do { do {
while (Eol()); while (Eol());
if (!Equation()) { if (!Equation()) {
throw Eval_Error("Unexpected value in parameter list", match_stack.back()); throw Eval_Error("Unexpected value in parameter list", File_Position(line, col), filename);
} }
} while (retval && Char(',')); } while (retval && Char(','));
} }
@@ -1065,7 +1231,7 @@ namespace chaiscript
do { do {
while (Eol()); while (Eol());
if (!Map_Pair()) { if (!Map_Pair()) {
throw Eval_Error("Unexpected value in container", match_stack.back()); throw Eval_Error("Unexpected value in container", File_Position(line, col), filename);
} }
} while (retval && Char(',')); } while (retval && Char(','));
} }
@@ -1746,7 +1912,7 @@ namespace chaiscript
Symbol("%=", true, true) || Symbol("<<=", true, true) || Symbol(">>=", true, true) || Symbol("%=", true, true) || Symbol("<<=", true, true) || Symbol(">>=", true, true) ||
Symbol("&=", true, true) || Symbol("^=", true, true) || Symbol("|=", true, true)) { Symbol("&=", true, true) || Symbol("^=", true, true) || Symbol("|=", true, true)) {
if (!Equation()) { if (!Equation()) {
throw Eval_Error("Incomplete equation", match_stack.back()); throw Eval_Error("Incomplete equation", File_Position(line, col), filename);
} }
build_match(Token_Type::Equation, prev_stack_top); build_match(Token_Type::Equation, prev_stack_top);
@@ -1767,9 +1933,11 @@ namespace chaiscript
while (has_more) { while (has_more) {
has_more = false; has_more = false;
int prev_line = line;
int prev_col = col;
if (Def()) { if (Def()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two function definitions missing line separator", match_stack.back()); throw Eval_Error("Two function definitions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;
@@ -1777,7 +1945,7 @@ namespace chaiscript
} }
else if (Try()) { else if (Try()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two function definitions missing line separator", match_stack.back()); throw Eval_Error("Two function definitions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;
@@ -1785,7 +1953,7 @@ namespace chaiscript
} }
else if (If()) { else if (If()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two function definitions missing line separator", match_stack.back()); throw Eval_Error("Two function definitions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;
@@ -1793,7 +1961,7 @@ namespace chaiscript
} }
else if (While()) { else if (While()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two function definitions missing line separator", match_stack.back()); throw Eval_Error("Two function definitions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;
@@ -1801,7 +1969,7 @@ namespace chaiscript
} }
else if (For()) { else if (For()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two function definitions missing line separator", match_stack.back()); throw Eval_Error("Two function definitions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;
@@ -1809,7 +1977,7 @@ namespace chaiscript
} }
else if (Return()) { else if (Return()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two expressions missing line separator", match_stack.back()); throw Eval_Error("Two expressions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;
@@ -1817,7 +1985,7 @@ namespace chaiscript
} }
else if (Break()) { else if (Break()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two expressions missing line separator", match_stack.back()); throw Eval_Error("Two expressions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;
@@ -1825,7 +1993,7 @@ namespace chaiscript
} }
else if (Equation()) { else if (Equation()) {
if (!saw_eol) { if (!saw_eol) {
throw Eval_Error("Two expressions missing line separator", match_stack.back()); throw Eval_Error("Two expressions missing line separator", File_Position(prev_line, prev_col), filename);
} }
has_more = true; has_more = true;
retval = true; retval = true;

View File

@@ -118,8 +118,16 @@ int main(int argc, char *argv[]) {
} }
} }
} }
catch (chaiscript::Eval_Error &ee) {
std::cout << ee.what();
if (ee.call_stack.size() > 0) {
std::cout << "during evaluation at (" << ee.call_stack[0]->start.line << ", " << ee.call_stack[0]->start.column << ")";
}
std::cout << std::endl;
}
catch (std::exception &e) { catch (std::exception &e) {
std::cout << e.what() << std::endl; std::cout << e.what();
std::cout << std::endl;
} }
} }
@@ -131,6 +139,13 @@ int main(int argc, char *argv[]) {
try { try {
chaiscript::Boxed_Value val = chai.eval_file(argv[i]); chaiscript::Boxed_Value val = chai.eval_file(argv[i]);
} }
catch (chaiscript::Eval_Error &ee) {
std::cout << ee.what();
if (ee.call_stack.size() > 0) {
std::cout << "during evaluation at (" << ee.call_stack[0]->start.line << ", " << ee.call_stack[0]->start.column << ")";
}
std::cout << std::endl;
}
catch (std::exception &e) { catch (std::exception &e) {
std::cout << e.what() << std::endl; std::cout << e.what() << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;