Exemplo n.º 1
0
bool GDScriptLanguage::validate(const String& p_script, int &r_line_error,int &r_col_error,String& r_test_error, const String& p_path,List<String> *r_functions) const {

	GDParser parser;

	Error err = parser.parse(p_script,p_path.get_base_dir(),true);
	if (err) {
		r_line_error=parser.get_error_line();
		r_col_error=parser.get_error_column();
		r_test_error=parser.get_error();
		return false;
	} else {

		const GDParser::Node *root = parser.get_parse_tree();
		ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,false);

		const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode*>(root);
		Map<int,String> funcs;
		for(int i=0;i<cl->functions.size();i++) {

			funcs[cl->functions[i]->line]=cl->functions[i]->name;
		}

		for(int i=0;i<cl->static_functions.size();i++) {

			funcs[cl->static_functions[i]->line]=cl->static_functions[i]->name;
		}

		for (Map<int,String>::Element *E=funcs.front();E;E=E->next()) {

			r_functions->push_back(E->get()+":"+itos(E->key()));
		}


	}

	return true;
}
Exemplo n.º 2
0
MainLoop* test(TestType p_test) {

	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]);

	Vector<String> lines;
	int last=0;

	for(int i=0;i<=code.length();i++) {

		if (code[i]=='\n' || code[i]==0) {

			lines.push_back(code.substr(last,i-last));
			last=i+1;
		}
	}


	if (p_test==TEST_TOKENIZER) {

		GDTokenizerText tk;
		tk.set_code(code);
		int line=-1;
		while(tk.get_token()!=GDTokenizer::TK_EOF) {


			String text;
			if (tk.get_token()==GDTokenizer::TK_IDENTIFIER)
				text="'"+tk.get_token_identifier()+"' (identifier)";
			else if (tk.get_token()==GDTokenizer::TK_CONSTANT) {
				Variant c= tk.get_token_constant();
				if (c.get_type()==Variant::STRING)
					text="\""+String(c)+"\"";
				else
					text=c;

				text=text+" ("+Variant::get_type_name(c.get_type())+" constant)";
			} else if (tk.get_token()==GDTokenizer::TK_ERROR)
				text="ERROR: "+tk.get_token_error();
			else if (tk.get_token()==GDTokenizer::TK_NEWLINE)
				text="newline ("+itos(tk.get_token_line())+") + indent: "+itos(tk.get_token_line_indent());
			else if (tk.get_token()==GDTokenizer::TK_BUILT_IN_FUNC)
				text="'"+String(GDFunctions::get_func_name(tk.get_token_built_in_func()))+"' (built-in function)";
			else
				text=tk.get_token_name(tk.get_token());


			if (tk.get_token_line()!=line) {
				int from=line+1;
				line = tk.get_token_line();;

				for(int i=from;i<=line;i++) {
					int l=i-1;
					if (l>=0 && l<lines.size()) {
						print_line("\n"+itos(i)+": "+lines[l]+"\n");
					}
				}
			}
			print_line("\t("+itos(tk.get_token_column())+"): "+text);
			tk.advance();

		}
	}

	if (p_test==TEST_PARSER) {


		GDParser parser;
		Error err = parser.parse(code);
		if (err) {
			print_line("Parse Error:\n"+itos(parser.get_error_line())+":"+itos(parser.get_error_column())+":"+parser.get_error());
			memdelete(fa);
			return NULL;

		}

		const GDParser::Node* root = parser.get_parse_tree();
		ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,NULL);
		const GDParser::ClassNode *cnode=static_cast<const GDParser::ClassNode*>(root);

		_parser_show_class(cnode,0,lines);

	}

	if (p_test==TEST_COMPILER) {


		GDParser parser;

		Error err = parser.parse(code);
		if (err) {
			print_line("Parse Error:\n"+itos(parser.get_error_line())+":"+itos(parser.get_error_column())+":"+parser.get_error());
			memdelete(fa);
			return NULL;

		}

		GDScript *script = memnew( GDScript );

		GDCompiler gdc;
		err = gdc.compile(&parser,script);
		if (err) {

			print_line("Compile Error:\n"+itos(gdc.get_error_line())+":"+itos(gdc.get_error_column())+":"+gdc.get_error());
			memdelete(script);
			return NULL;

		}


		Ref<GDScript> gds =Ref<GDScript>( script );

		Ref<GDScript> current=gds;

		while(current.is_valid()) {

			print_line("** CLASS **");
			_disassemble_class(current,lines);

			current=current->get_base();
		}




	} else if (p_test==TEST_BYTECODE) {

		Vector<uint8_t> buf = GDTokenizerBuffer::parse_code_string(code);
		String dst = test.basename()+".gdc";
		FileAccess *fw = FileAccess::open(dst,FileAccess::WRITE);
		fw->store_buffer(buf.ptr(),buf.size());
		memdelete(fw);
	}


#if 0
	Parser parser;
	Error err = parser.parse(code);
	if (err) {
		print_line("error:"+itos(parser.get_error_line())+":"+itos(parser.get_error_column())+":"+parser.get_error());
	} else {
		print_line("Parse O-K!");
	}
#endif



	memdelete(fa);

	return NULL;
}