Merge branch 'master' into ChaiScript_5_0_CPP_11
Conflicts: include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_parser.hpp
This commit is contained in:
commit
dd79534de1
10
contrib/codeanalysis/heterogenous_array_loop.chai
Normal file
10
contrib/codeanalysis/heterogenous_array_loop.chai
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
var my_array=["1", 4, 6.6l, 10ul, "1000", 100, 10.9f ];
|
||||||
|
|
||||||
|
for (var j = 0; j < 10000; ++j)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 6; ++i)
|
||||||
|
{
|
||||||
|
to_string(my_array[i]);
|
||||||
|
}
|
||||||
|
}
|
@ -21,9 +21,9 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl,
|
enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl,
|
||||||
Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String,
|
Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String,
|
||||||
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Map_Pair, Value_Range,
|
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
||||||
Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or,
|
Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or,
|
||||||
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond
|
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,9 +35,9 @@ namespace chaiscript
|
|||||||
const char *ast_node_type_to_string(int ast_node_type) {
|
const char *ast_node_type_to_string(int ast_node_type) {
|
||||||
const char *ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl",
|
const char *ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl",
|
||||||
"Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String",
|
"Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String",
|
||||||
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Map_Pair", "Value_Range",
|
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
||||||
"Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or",
|
"Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or",
|
||||||
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition"};
|
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop"};
|
||||||
|
|
||||||
return ast_node_types[ast_node_type];
|
return ast_node_types[ast_node_type];
|
||||||
}
|
}
|
||||||
@ -494,6 +494,14 @@ namespace chaiscript
|
|||||||
Break_Loop() { }
|
Break_Loop() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special type indicating a call to 'continue'
|
||||||
|
*/
|
||||||
|
struct Continue_Loop {
|
||||||
|
Continue_Loop() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Creates a new scope then pops it on destruction
|
/// Creates a new scope then pops it on destruction
|
||||||
struct Scope_Push_Pop
|
struct Scope_Push_Pop
|
||||||
{
|
{
|
||||||
|
@ -821,8 +821,14 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("While condition not boolean");
|
throw exception::eval_error("While condition not boolean");
|
||||||
}
|
}
|
||||||
while (cond) {
|
while (cond) {
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
this->children[1]->eval(t_ss);
|
this->children[1]->eval(t_ss);
|
||||||
|
} catch (detail::Continue_Loop &) {
|
||||||
|
// we got a continue exception, which means all of the remaining
|
||||||
|
// loop implementation is skipped and we just need to continue to
|
||||||
|
// the next condition test
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
@ -933,13 +939,27 @@ namespace chaiscript
|
|||||||
while (cond) {
|
while (cond) {
|
||||||
try {
|
try {
|
||||||
if (this->children.size() == 4) {
|
if (this->children.size() == 4) {
|
||||||
|
|
||||||
|
try {
|
||||||
this->children[3]->eval(t_ss);
|
this->children[3]->eval(t_ss);
|
||||||
|
} catch (detail::Continue_Loop &) {
|
||||||
|
// we got a continue exception, which means all of the remaining
|
||||||
|
// loop implementation is skipped and we just need to continue to
|
||||||
|
// the next iteration step
|
||||||
|
}
|
||||||
|
|
||||||
this->children[2]->eval(t_ss);
|
this->children[2]->eval(t_ss);
|
||||||
|
|
||||||
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
try {
|
||||||
this->children[2]->eval(t_ss);
|
this->children[2]->eval(t_ss);
|
||||||
|
} catch (detail::Continue_Loop &) {
|
||||||
|
// we got a continue exception, which means all of the remaining
|
||||||
|
// loop implementation is skipped and we just need to continue to
|
||||||
|
// the next iteration step
|
||||||
|
}
|
||||||
|
|
||||||
this->children[1]->eval(t_ss);
|
this->children[1]->eval(t_ss);
|
||||||
|
|
||||||
@ -1168,6 +1188,33 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Continue_AST_Node : public AST_Node {
|
||||||
|
public:
|
||||||
|
Continue_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Continue, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
|
||||||
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
|
virtual ~Continue_AST_Node() {}
|
||||||
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
|
||||||
|
throw detail::Continue_Loop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Noop_AST_Node : public AST_Node {
|
||||||
|
public:
|
||||||
|
Noop_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Noop, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
|
||||||
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
||||||
|
m_value(const_var(true))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual ~Noop_AST_Node() {}
|
||||||
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
|
||||||
|
// It's a no-op, that evaluates to "true"
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Boxed_Value m_value;
|
||||||
|
};
|
||||||
|
|
||||||
struct Map_Pair_AST_Node : public AST_Node {
|
struct Map_Pair_AST_Node : public AST_Node {
|
||||||
public:
|
public:
|
||||||
Map_Pair_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Map_Pair, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
|
Map_Pair_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Map_Pair, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
|
||||||
|
@ -1565,19 +1565,41 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the C-style for conditions from input
|
* Reads the C-style for conditions from input
|
||||||
*/
|
*/
|
||||||
bool For_Guards() {
|
bool For_Guards() {
|
||||||
Equation();
|
if (!(Equation() && Eol()))
|
||||||
|
{
|
||||||
|
if (!Eol())
|
||||||
|
{
|
||||||
|
throw exception::eval_error("'for' loop initial statment missing", File_Position(m_line, m_col), *m_filename);
|
||||||
|
} else {
|
||||||
|
AST_NodePtr t(new eval::Noop_AST_Node());
|
||||||
|
m_match_stack.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Equation() && Eol()))
|
||||||
|
{
|
||||||
|
if (!Eol())
|
||||||
|
{
|
||||||
|
throw exception::eval_error("'for' loop condition missing", File_Position(m_line, m_col), *m_filename);
|
||||||
|
} else {
|
||||||
|
AST_NodePtr t(new eval::Noop_AST_Node());
|
||||||
|
m_match_stack.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Equation())
|
||||||
|
{
|
||||||
|
AST_NodePtr t(new eval::Noop_AST_Node());
|
||||||
|
m_match_stack.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
if (Char(';') && Operator() && Char(';') && Equation()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
throw exception::eval_error("Incomplete conditions in 'for' loop", File_Position(m_line, m_col), *m_filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a for block from input
|
* Reads a for block from input
|
||||||
@ -1751,6 +1773,23 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a continue statement from input
|
||||||
|
*/
|
||||||
|
bool Continue() {
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
size_t prev_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
|
if (Keyword("continue")) {
|
||||||
|
retval = true;
|
||||||
|
|
||||||
|
build_match(AST_NodePtr(new eval::Continue_AST_Node()), prev_stack_top);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a dot expression(member access), then proceeds to check if it's a function or array call
|
* Reads a dot expression(member access), then proceeds to check if it's a function or array call
|
||||||
*/
|
*/
|
||||||
@ -2276,6 +2315,14 @@ namespace chaiscript
|
|||||||
retval = true;
|
retval = true;
|
||||||
saw_eol = false;
|
saw_eol = false;
|
||||||
}
|
}
|
||||||
|
else if (Continue()) {
|
||||||
|
if (!saw_eol) {
|
||||||
|
throw exception::eval_error("Two expressions missing line separator", File_Position(prev_line, prev_col), *m_filename);
|
||||||
|
}
|
||||||
|
has_more = true;
|
||||||
|
retval = true;
|
||||||
|
saw_eol = false;
|
||||||
|
}
|
||||||
else if (Block()) {
|
else if (Block()) {
|
||||||
has_more = true;
|
has_more = true;
|
||||||
retval = true;
|
retval = true;
|
||||||
|
11
unittests/break_for.chai
Normal file
11
unittests/break_for.chai
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
var j = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < 10; ++i) {
|
||||||
|
if (i == 5) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
j = i
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(4, j);
|
16
unittests/continue_for.chai
Normal file
16
unittests/continue_for.chai
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
var j = 0;
|
||||||
|
var k = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
j = i
|
||||||
|
if (i > 5)
|
||||||
|
{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
k = i
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(5, k);
|
||||||
|
assert_equal(9, j);
|
14
unittests/continue_while.chai
Normal file
14
unittests/continue_while.chai
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
var i = 0
|
||||||
|
var j = 0
|
||||||
|
|
||||||
|
while (i < 10) {
|
||||||
|
if (++i > 5)
|
||||||
|
{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(10, i);
|
||||||
|
assert_equal(5, j);
|
@ -5,3 +5,57 @@ for (auto i = 0; i < 5; ++i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_equal([0,1,2,3,4], ret);
|
assert_equal([0,1,2,3,4], ret);
|
||||||
|
|
||||||
|
|
||||||
|
var j = 0;
|
||||||
|
|
||||||
|
for (;j<10; ++j)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(10, j);
|
||||||
|
|
||||||
|
|
||||||
|
var k = 0;
|
||||||
|
|
||||||
|
for (;k<10; )
|
||||||
|
{
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(10, k);
|
||||||
|
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var l = 0;
|
||||||
|
|
||||||
|
for (;;l = 1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(0, l)
|
||||||
|
|
||||||
|
def isNotFive(x)
|
||||||
|
{
|
||||||
|
if (x != 5)
|
||||||
|
{
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var m;
|
||||||
|
|
||||||
|
for (m = 0; isNotFive(m); m = m + 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(5, m);
|
||||||
|
|
||||||
|
3
unittests/vector_of_suffixed_numbers.chai
Normal file
3
unittests/vector_of_suffixed_numbers.chai
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
var x = [1, 2u, 3.0l]
|
||||||
|
assert_equal(3.0l, x[2])
|
||||||
|
assert_equal(2u, x[1])
|
Loading…
x
Reference in New Issue
Block a user