summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/tests/test_math.cpp400
1 files changed, 399 insertions, 1 deletions
diff --git a/bin/tests/test_math.cpp b/bin/tests/test_math.cpp
index 4b686e8af8..e5667bff64 100644
--- a/bin/tests/test_math.cpp
+++ b/bin/tests/test_math.cpp
@@ -40,12 +40,376 @@
#include "scene/resources/texture.h"
#include "vmap.h"
#include "os/os.h"
+#include "os/file_access.h"
#include "method_ptrcall.h"
namespace TestMath {
+class GetClassAndNamespace {
+
+ String code;
+ int idx;
+ int line;
+ String error_str;
+ bool error;
+ Variant value;
+
+ String class_name;
+
+ enum Token {
+ TK_BRACKET_OPEN,
+ TK_BRACKET_CLOSE,
+ TK_CURLY_BRACKET_OPEN,
+ TK_CURLY_BRACKET_CLOSE,
+ TK_PERIOD,
+ TK_COLON,
+ TK_COMMA,
+ TK_SYMBOL,
+ TK_IDENTIFIER,
+ TK_STRING,
+ TK_NUMBER,
+ TK_EOF,
+ TK_ERROR
+ };
+
+
+ Token get_token() {
+
+ while (true) {
+ switch(code[idx]) {
+
+ case '\n': {
+
+ line++;
+ idx++;
+ break;
+ };
+ case 0: {
+ return TK_EOF;
+
+ } break;
+ case '{': {
+
+ idx++;
+ return TK_CURLY_BRACKET_OPEN;
+ };
+ case '}': {
+
+ idx++;
+ return TK_CURLY_BRACKET_CLOSE;
+ };
+ case '[': {
+
+ idx++;
+ return TK_BRACKET_OPEN;
+ };
+ case ']': {
+
+ idx++;
+ return TK_BRACKET_CLOSE;
+ };
+ case ':': {
+
+ idx++;
+ return TK_COLON;
+ };
+ case ',': {
+
+ idx++;
+ return TK_COMMA;
+ };
+ case '.': {
+
+ idx++;
+ return TK_PERIOD;
+ };
+ case '#': {
+ //compiler directive
+ while(code[idx]!='\n' && code[idx]!=0) {
+ idx++;
+ }
+ continue;
+ } break;
+ case '/': {
+
+
+ switch(code[idx+1]) {
+ case '*': { // block comment
+
+ idx+=2;
+ while(true) {
+ if (code[idx]==0) {
+ error_str="Unterminated comment";
+ error=true;
+ return TK_ERROR;
+ } if (code[idx]=='*' &&code[idx+1]=='/') {
+
+ idx+=2;
+ break;
+ } if (code[idx]=='\n') {
+ line++;
+ }
+
+ idx++;
+ }
+
+ } break;
+ case '/': { // line comment skip
+
+ while(code[idx]!='\n' && code[idx]!=0) {
+ idx++;
+ }
+
+ } break;
+ default: {
+ value="/";
+ idx++;
+ return TK_SYMBOL;
+ }
+
+ }
+
+ continue; // a comment
+ } break;
+ case '\'':
+ case '"': {
+
+ CharType begin_str = code[idx];
+ idx++;
+ String tk_string=String();
+ while(true) {
+ if (code[idx]==0) {
+ error_str="Unterminated String";
+ error=true;
+ return TK_ERROR;
+ } else if (code[idx]==begin_str) {
+ idx++;
+ break;
+ } else if (code[idx]=='\\') {
+ //escaped characters...
+ idx++;
+ CharType next = code[idx];
+ if (next==0) {
+ error_str="Unterminated String";
+ error=true;
+ return TK_ERROR;
+ }
+ CharType res=0;
+
+ switch(next) {
+
+ case 'b': res=8; break;
+ case 't': res=9; break;
+ case 'n': res=10; break;
+ case 'f': res=12; break;
+ case 'r': res=13; break;
+ /* too much, not needed for now
+ case 'u': {
+ //hexnumbarh - oct is deprecated
+
+
+ for(int j=0;j<4;j++) {
+ CharType c = code[idx+j+1];
+ if (c==0) {
+ r_err_str="Unterminated String";
+ return ERR_PARSE_ERROR;
+ }
+ if (!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))) {
+
+ r_err_str="Malformed hex constant in string";
+ return ERR_PARSE_ERROR;
+ }
+ CharType v;
+ if (c>='0' && c<='9') {
+ v=c-'0';
+ } else if (c>='a' && c<='f') {
+ v=c-'a';
+ v+=10;
+ } else if (c>='A' && c<='F') {
+ v=c-'A';
+ v+=10;
+ } else {
+ ERR_PRINT("BUG");
+ v=0;
+ }
+
+ res<<=4;
+ res|=v;
+
+
+ }
+ idx+=4; //will add at the end anyway
+
+
+ } break;*/
+ case '\"': res='\"'; break;
+ case '\\': res='\\'; break;
+ //case '/': res='/'; break;
+ default: {
+ res = next;
+ //r_err_str="Invalid escape sequence";
+ //return ERR_PARSE_ERROR;
+ } break;
+ }
+
+ tk_string+=res;
+
+ } else {
+ if (code[idx]=='\n')
+ line++;
+ tk_string+=code[idx];
+ }
+ idx++;
+ }
+
+ value=tk_string;
+
+ return TK_STRING;
+
+ } break;
+ default: {
+
+ if (code[idx]<=32) {
+ idx++;
+ break;
+ }
+
+ if ( (code[idx]>=33 && code[idx]<=47) || (code[idx]>=58 && code[idx]<=64) || (code[idx]>=91 && code[idx]<=96) || (code[idx]>=123 && code[idx]<=127)){
+ value=String::chr(code[idx]);
+ idx++;
+ return TK_SYMBOL;
+ }
+
+ if (code[idx]=='-' || (code[idx]>='0' && code[idx]<='9')) {
+ //a number
+ const CharType *rptr;
+ double number = String::to_double(&code[idx],&rptr);
+ idx+=(rptr - &code[idx]);
+ value=number;
+ return TK_NUMBER;
+
+ } else if ((code[idx]>='A' && code[idx]<='Z') || (code[idx]>='a' && code[idx]<='z') || code[idx]>127) {
+
+ String id;
+
+ while((code[idx]>='A' && code[idx]<='Z') || (code[idx]>='a' && code[idx]<='z') || code[idx]>127) {
+
+ id+=code[idx];
+ idx++;
+ }
+
+ value=id;
+ return TK_IDENTIFIER;
+ } else {
+ error_str="Unexpected character.";
+ error=true;
+ return TK_ERROR;
+ }
+ }
+
+ }
+ }
+ }
+
+public:
+ Error parse(const String& p_code,const String& p_known_class_name=String()) {
+
+ code=p_code;
+ idx=0;
+ line=0;
+ error_str=String();
+ error=false;
+ value=Variant();
+ class_name=String();
+
+ bool use_next_class=false;
+ Token tk = get_token();
+
+ Map<int,String> namespace_stack;
+ int curly_stack=0;
+
+
+ while(!error || tk!=TK_EOF) {
+
+ if (tk==TK_BRACKET_OPEN) {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER && String(value)=="ScriptClass") {
+ if (get_token()==TK_BRACKET_CLOSE) {
+ use_next_class=true;
+ }
+ }
+ } else if (tk==TK_IDENTIFIER && String(value)=="class") {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER) {
+ String name = value;
+ if (use_next_class || p_known_class_name==name) {
+ for (Map<int,String>::Element *E=namespace_stack.front();E;E=E->next()) {
+ class_name+=E->get()+".";
+ }
+ class_name+=String(value);
+ break;
+ }
+ }
+
+ } else if (tk==TK_IDENTIFIER && String(value)=="namespace") {
+ String name;
+ int at_level = curly_stack;
+ while(true) {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER) {
+ name+=String(value);
+ }
+
+ tk = get_token();
+ if (tk==TK_PERIOD) {
+ name+=".";
+ } else if (tk==TK_CURLY_BRACKET_OPEN) {
+ curly_stack++;
+ break;
+ } else {
+ break; //whathever else
+ }
+
+ }
+
+ if (name!=String()) {
+ namespace_stack[at_level]=name;
+ }
+
+ } else if (tk==TK_CURLY_BRACKET_OPEN) {
+ curly_stack++;
+ } else if (tk==TK_CURLY_BRACKET_CLOSE) {
+ curly_stack--;
+ if (namespace_stack.has(curly_stack)) {
+ namespace_stack.erase(curly_stack);
+ }
+ }
+
+ tk = get_token();
+ }
+
+ if (error)
+ return ERR_PARSE_ERROR;
+
+
+
+ return OK;
+
+ }
+
+ String get_error() {
+ return error_str;
+ }
+
+ String get_class() {
+ return class_name;
+ }
+
+};
+
+
void test_vec(Plane p_vec) {
@@ -113,7 +477,41 @@ uint32_t ihash3( uint32_t a)
MainLoop* test() {
- print_line(itos(Math::step_decimals( 0.0001 )));
+
+ List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
+
+ if (cmdlargs.empty()) {
+ //try editor!
+ return NULL;
+ }
+
+ String test = cmdlargs.back()->get();
+
+ FileAccess *fa = FileAccess::open(test,FileAccess::READ);
+
+ if (!fa) {
+ ERR_EXPLAIN("Could not open file: "+test);
+ ERR_FAIL_V(NULL);
+ }
+
+
+ Vector<uint8_t> buf;
+ int flen = fa->get_len();
+ buf.resize(fa->get_len()+1);
+ fa->get_buffer(&buf[0],flen);
+ buf[flen]=0;
+
+
+ String code;
+ code.parse_utf8((const char*)&buf[0]);
+
+ GetClassAndNamespace getclass;
+ if (getclass.parse(code)) {
+ print_line("Parse error: "+getclass.get_error());
+ } else {
+ print_line("Found class: "+getclass.get_class());
+ }
+
return NULL;
{