diff --git a/version2.0/nasal_enum.h b/version2.0/nasal_enum.h index 16fe10a..d93171b 100644 --- a/version2.0/nasal_enum.h +++ b/version2.0/nasal_enum.h @@ -283,7 +283,7 @@ void print_parse_error(int error_type,int line,int error_token_type=__stack_end) std::cout<<"\' when generating definition."< >& local_scop return call_identifier(local_scope,node); else if(node_type==__add_operator || node_type==__sub_operator || node_type==__mul_operator || node_type==__div_operator) { - // scalar_nil canot be used here + // scalar_nil cannot be used here int ret_addr=-1; int addr_1=-1; int addr_2=-1; @@ -324,7 +333,7 @@ int nasal_runtime::calculation(std::list >& local_scop nasal_gc.reference_delete(addr_2); return ret_addr; } - else if(node_type==__cmp_equal || node_type==__cmp_not_equal || node_type==__cmp_less || node_type==__cmp_less_or_equal || node_type==__cmp_more || node_type==__cmp_more_or_equal) + else if(node_type==__cmp_equal || node_type==__cmp_not_equal) { int ret_addr=-1; int addr_1=calculation(local_scope,node.get_children().front()); @@ -335,30 +344,148 @@ int nasal_runtime::calculation(std::list >& local_scop int type_1=nasal_gc.get_scalar(addr_1).get_type(); int type_2=nasal_gc.get_scalar(addr_2).get_type(); // note: cmp operator change strings into numbers then making comparation + ret_addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(ret_addr).set_type(scalar_number); if(type_1==scalar_number && type_2==scalar_number) { - ; + double num_1=nasal_gc.get_scalar(addr_1).get_number().get_number(); + double num_2=nasal_gc.get_scalar(addr_2).get_number().get_number(); + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type==__cmp_equal?num_1==num_2:num_1!=num_2))); } else if(type_1==scalar_number && type_2==scalar_string) { - ; + double num_1=nasal_gc.get_scalar(addr_1).get_number().get_number(); + double num_2=0; + std::string tmp_str=nasal_gc.get_scalar(addr_2).get_string().get_string(); + if(check_numerable_string(tmp_str)) + num_2=trans_string_to_number(tmp_str); + else + { + error_interrupt(__not_numerable_str,node.get_children().back().get_node_line()); + return -1; + } + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type==__cmp_equal?num_1==num_2:num_1!=num_2))); } else if(type_1==scalar_string && type_2==scalar_number) { - ; + double num_1=0; + double num_2=nasal_gc.get_scalar(addr_2).get_number().get_number(); + std::string tmp_str=nasal_gc.get_scalar(addr_1).get_string().get_string(); + if(check_numerable_string(tmp_str)) + num_1=trans_string_to_number(tmp_str); + else + { + error_interrupt(__not_numerable_str,node.get_children().front().get_node_line()); + return -1; + } + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type==__cmp_equal?num_1==num_2:num_1!=num_2))); } else if(type_1==scalar_string && type_2==scalar_string) { - ; + std::string str_1=nasal_gc.get_scalar(addr_1).get_string().get_string(); + std::string str_2=nasal_gc.get_scalar(addr_2).get_string().get_string(); + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type==__cmp_equal?str_1==str_2:str_1!=str_2))); + } + else if(type_1==scalar_vector && type_2==scalar_vector) + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type==__cmp_equal?addr_1==addr_2:addr_1!=addr_2))); + else if(type_1==scalar_hash && type_2==scalar_hash) + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type==__cmp_equal?addr_1==addr_2:addr_1!=addr_2))); + else if(type_1==scalar_function && type_2==scalar_function) + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type==__cmp_equal?addr_1==addr_2:addr_1!=addr_2))); + else if(type_1!=type_2) + nasal_gc.get_scalar(ret_addr).get_number().set_number((double(node_type!=__cmp_equal))); + else + { + error_interrupt(__error_value_type,node.get_node_line()); + return -1; + } + nasal_gc.reference_delete(addr_1); + nasal_gc.reference_delete(addr_2); + return ret_addr; + } + else if(node_type==__cmp_less || node_type==__cmp_less_or_equal || node_type==__cmp_more || node_type==__cmp_more_or_equal) + { + int ret_addr=-1; + int addr_1=calculation(local_scope,node.get_children().front()); + int addr_2=calculation(local_scope,node.get_children().back()); + // check if the address is available + if(addr_1<0 || addr_2<0) + return -1; + int type_1=nasal_gc.get_scalar(addr_1).get_type(); + int type_2=nasal_gc.get_scalar(addr_2).get_type(); + // note: cmp operator change strings into numbers then making comparation + // only numbers and strings can take these calculations + ret_addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(ret_addr).set_type(scalar_number); + if(type_1==scalar_number && type_2==scalar_number) + { + double num_1=nasal_gc.get_scalar(addr_1).get_number().get_number(); + double num_2=nasal_gc.get_scalar(addr_2).get_number().get_number(); + switch(node_type) + { + case __cmp_less:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(num_1num_2)));break; + case __cmp_more_or_equal:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(num_1>=num_2)));break; + } + } + else if(type_1==scalar_number && type_2==scalar_string) + { + double num_1=nasal_gc.get_scalar(addr_1).get_number().get_number(); + double num_2=0; + std::string tmp_str=nasal_gc.get_scalar(addr_2).get_string().get_string(); + if(check_numerable_string(tmp_str)) + num_2=trans_string_to_number(tmp_str); + else + { + error_interrupt(__not_numerable_str,node.get_children().back().get_node_line()); + return -1; + } + switch(node_type) + { + case __cmp_less:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(num_1num_2)));break; + case __cmp_more_or_equal:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(num_1>=num_2)));break; + } + } + else if(type_1==scalar_string && type_2==scalar_number) + { + double num_1=0; + double num_2=nasal_gc.get_scalar(addr_2).get_number().get_number(); + std::string tmp_str=nasal_gc.get_scalar(addr_1).get_string().get_string(); + if(check_numerable_string(tmp_str)) + num_1=trans_string_to_number(tmp_str); + else + { + error_interrupt(__not_numerable_str,node.get_children().front().get_node_line()); + return -1; + } + switch(node_type) + { + case __cmp_less:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(num_1num_2)));break; + case __cmp_more_or_equal:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(num_1>=num_2)));break; + } + } + else if(type_1==scalar_string && type_2==scalar_string) + { + std::string str_1=nasal_gc.get_scalar(addr_1).get_string().get_string(); + std::string str_2=nasal_gc.get_scalar(addr_2).get_string().get_string(); + switch(node_type) + { + case __cmp_less:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(str_1str_2)));break; + case __cmp_more_or_equal:nasal_gc.get_scalar(ret_addr).get_number().set_number((double(str_1>=str_2)));break; + } } else { error_interrupt(__error_value_type,node.get_node_line()); return -1; } - ret_addr=nasal_gc.gc_alloc(); - nasal_gc.get_scalar(ret_addr).set_type(scalar_number); - // nasal_gc.reference_delete(addr_1); nasal_gc.reference_delete(addr_2); return ret_addr; @@ -370,7 +497,10 @@ int nasal_runtime::calculation(std::list >& local_scop else if(node_type==__add_equal || node_type==__sub_equal || node_type==__mul_equal || node_type==__div_equal || node_type==__link_equal) { // scalar_nil also cannot be used here - ; + int id_addr=call_identifier(local_scope,node.get_children().front()); + int value_addr=calculation(local_scope,node.get_children().back()); + if(id_addr<0 || value_addr<0) + return -1; } else if(node_type==__and_operator || node_type==__or_operator || node_type==__nor_operator) { @@ -393,7 +523,24 @@ int nasal_runtime::call_identifier(std::list >& local_ for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) if(iter->find(tmp_id_name)!=iter->end()) addr=(*iter)[tmp_id_name]; - return -1; + if(addr<0) + { + error_interrupt(__undefined_identifier,node.get_node_line()); + return -1; + } + for(std::list::iterator iter=node.get_children().begin();iter!=node.get_children().end();++iter) + { + int node_type=iter->get_node_type(); + if(node_type==__call_vector) + ; + else if(node_type==__call_hash) + ; + else if(node_type==__call_function) + ; + else + ; + } + return addr; } void nasal_runtime::definition(std::list >& local_scope,abstract_syntax_tree& node) {