From 4b07eb8deb03ce8c7870d621cd03d04d45f4caaa Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 24 Feb 2014 09:53:33 -0300 Subject: -moved script to modules --- script/gdscript/SCsub | 7 - script/gdscript/gd_compiler.cpp | 1531 ---------------------- script/gdscript/gd_compiler.h | 181 --- script/gdscript/gd_editor.cpp | 789 ----------- script/gdscript/gd_functions.cpp | 1218 ----------------- script/gdscript/gd_functions.h | 103 -- script/gdscript/gd_parser.cpp | 2469 ----------------------------------- script/gdscript/gd_parser.h | 397 ------ script/gdscript/gd_pretty_print.cpp | 34 - script/gdscript/gd_pretty_print.h | 40 - script/gdscript/gd_script.cpp | 2222 ------------------------------- script/gdscript/gd_script.h | 473 ------- script/gdscript/gd_tokenizer.cpp | 973 -------------- script/gdscript/gd_tokenizer.h | 181 --- 14 files changed, 10618 deletions(-) delete mode 100644 script/gdscript/SCsub delete mode 100644 script/gdscript/gd_compiler.cpp delete mode 100644 script/gdscript/gd_compiler.h delete mode 100644 script/gdscript/gd_editor.cpp delete mode 100644 script/gdscript/gd_functions.cpp delete mode 100644 script/gdscript/gd_functions.h delete mode 100644 script/gdscript/gd_parser.cpp delete mode 100644 script/gdscript/gd_parser.h delete mode 100644 script/gdscript/gd_pretty_print.cpp delete mode 100644 script/gdscript/gd_pretty_print.h delete mode 100644 script/gdscript/gd_script.cpp delete mode 100644 script/gdscript/gd_script.h delete mode 100644 script/gdscript/gd_tokenizer.cpp delete mode 100644 script/gdscript/gd_tokenizer.h (limited to 'script/gdscript') diff --git a/script/gdscript/SCsub b/script/gdscript/SCsub deleted file mode 100644 index dd812edec5..0000000000 --- a/script/gdscript/SCsub +++ /dev/null @@ -1,7 +0,0 @@ -Import('env') - -env.add_source_files(env.script_sources,"*.cpp") - -Export('env') - - diff --git a/script/gdscript/gd_compiler.cpp b/script/gdscript/gd_compiler.cpp deleted file mode 100644 index dd2834bf34..0000000000 --- a/script/gdscript/gd_compiler.cpp +++ /dev/null @@ -1,1531 +0,0 @@ -/*************************************************************************/ -/* gd_compiler.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "gd_compiler.h" -#include "gd_script.h" -/* TODO: - - *AND and OR need early abort - -Inheritance properly process (done?) - *create built in initializer and constructor - *assign operators - *build arrays and dictionaries - *call parent constructor - */ - - -void GDCompiler::_set_error(const String& p_error,const GDParser::Node *p_node) { - - if (error!="") - return; - - error=p_error; - err_line=p_node->line; - err_column=p_node->column; -} - -bool GDCompiler::_create_unary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level) { - - ERR_FAIL_COND_V(on->arguments.size()!=1,false); - - int src_address_a = _parse_expression(codegen,on->arguments[0],p_stack_level); - if (src_address_a<0) - return false; - - codegen.opcodes.push_back(GDFunction::OPCODE_OPERATOR); // perform operator - codegen.opcodes.push_back(op); //which operator - codegen.opcodes.push_back(src_address_a); // argument 1 - codegen.opcodes.push_back(GDFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter) - return true; -} - -bool GDCompiler::_create_binary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level) { - - ERR_FAIL_COND_V(on->arguments.size()!=2,false); - - - int src_address_a = _parse_expression(codegen,on->arguments[0],p_stack_level); - if (src_address_a<0) - return false; - if (src_address_a&GDFunction::ADDR_TYPE_STACK<arguments[1],p_stack_level); - if (src_address_b<0) - return false; - - - codegen.opcodes.push_back(GDFunction::OPCODE_OPERATOR); // perform operator - codegen.opcodes.push_back(op); //which operator - codegen.opcodes.push_back(src_address_a); // argument 1 - codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter) - return true; -} - - -/* -int GDCompiler::_parse_subexpression(CodeGen& codegen,const GDParser::Node *p_expression) { - - - int ret = _parse_expression(codegen,p_expression); - if (ret<0) - return ret; - - if (ret&(GDFunction::ADDR_TYPE_STACK<op) { - - case GDParser::OperatorNode::OP_ASSIGN_ADD: var_op=Variant::OP_ADD; break; - case GDParser::OperatorNode::OP_ASSIGN_SUB: var_op=Variant::OP_SUBSTRACT; break; - case GDParser::OperatorNode::OP_ASSIGN_MUL: var_op=Variant::OP_MULTIPLY; break; - case GDParser::OperatorNode::OP_ASSIGN_DIV: var_op=Variant::OP_DIVIDE; break; - case GDParser::OperatorNode::OP_ASSIGN_MOD: var_op=Variant::OP_MODULE; break; - case GDParser::OperatorNode::OP_ASSIGN_SHIFT_LEFT: var_op=Variant::OP_SHIFT_LEFT; break; - case GDParser::OperatorNode::OP_ASSIGN_SHIFT_RIGHT: var_op=Variant::OP_SHIFT_RIGHT; break; - case GDParser::OperatorNode::OP_ASSIGN_BIT_AND: var_op=Variant::OP_BIT_AND; break; - case GDParser::OperatorNode::OP_ASSIGN_BIT_OR: var_op=Variant::OP_BIT_OR; break; - case GDParser::OperatorNode::OP_ASSIGN_BIT_XOR: var_op=Variant::OP_BIT_XOR; break; - case GDParser::OperatorNode::OP_ASSIGN: { - - //none - } break; - default: { - - ERR_FAIL_V(-1); - } - } - - if (var_op==Variant::OP_MAX) { - - return _parse_expression(codegen,p_expression->arguments[1],p_stack_level); - } - - if (!_create_binary_operator(codegen,p_expression,var_op,p_stack_level)) - return -1; - - int dst_addr=(p_stack_level)|(GDFunction::ADDR_TYPE_STACK<type) { - //should parse variable declaration and adjust stack accordingly... - case GDParser::Node::TYPE_IDENTIFIER: { - //return identifier - //wait, identifier could be a local variable or something else... careful here, must reference properly - //as stack may be more interesting to work with - - //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases peformance a lot. - - const GDParser::IdentifierNode *in = static_cast(p_expression); - - StringName identifier = in->name; - - // TRY STACK! - if (codegen.stack_identifiers.has(identifier)) { - - int pos = codegen.stack_identifiers[identifier]; - return pos|(GDFunction::ADDR_TYPE_STACK_VARIABLE<_static) { - - // TRY MEMBER VARIABLES! - - //static function - if (codegen.script->member_indices.has(identifier)) { - - int idx = codegen.script->member_indices[identifier]; - return idx|(GDFunction::ADDR_TYPE_MEMBER<constants.has(identifier)) { - - //int idx=scr->constants[identifier]; - int idx = codegen.get_name_map_pos(identifier); - return idx|(GDFunction::ADDR_TYPE_CLASS_CONSTANT<native.is_valid()) - nc=scr->native.ptr(); - scr=scr->_base; - } - - // CLASS C++ Integer Constant - - if (nc) { - - bool success=false; - int constant = ObjectTypeDB::get_integer_constant(nc->get_name(),identifier,&success); - if (success) { - Variant key=constant; - int idx; - - if (!codegen.constant_map.has(key)) { - - idx=codegen.constant_map.size(); - codegen.constant_map[key]=idx; - - } else { - idx=codegen.constant_map[key]; - } - - return idx|(GDFunction::ADDR_TYPE_LOCAL_CONSTANT<subclasses.has(identifier)) { - //same with a subclass, make it a local constant. - int idx = codegen.get_constant_pos(codegen.script->subclasses[identifier]); - return idx|(GDFunction::ADDR_TYPE_LOCAL_CONSTANT<get_global_map().has(identifier)) { - - int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier]; - return idx|(GDFunction::ADDR_TYPE_GLOBAL<(p_expression); - - - int idx; - - if (!codegen.constant_map.has(cn->value)) { - - idx=codegen.constant_map.size(); - codegen.constant_map[cn->value]=idx; - - } else { - idx=codegen.constant_map[cn->value]; - } - - - return idx|(GDFunction::ADDR_TYPE_LOCAL_CONSTANT<_static) { - _set_error("'self' not present in static function!",p_expression); - return -1; - } - return (GDFunction::ADDR_TYPE_SELF<(p_expression); - Vector values; - - int slevel=p_stack_level; - - for(int i=0;ielements.size();i++) { - - int ret = _parse_expression(codegen,an->elements[i],slevel); - if (ret<0) - return ret; - if (ret&GDFunction::ADDR_TYPE_STACK<(p_expression); - Vector values; - - int slevel=p_stack_level; - - for(int i=0;ielements.size();i++) { - - int ret = _parse_expression(codegen,dn->elements[i].key,slevel); - if (ret<0) - return ret; - if (ret&GDFunction::ADDR_TYPE_STACK<elements[i].value,slevel); - if (ret<0) - return ret; - if (ret&GDFunction::ADDR_TYPE_STACK<elements.size()); - for(int i=0;i(p_expression); - switch(on->op) { - - - //call/constructor operator - case GDParser::OperatorNode::OP_PARENT_CALL: { - - - ERR_FAIL_COND_V(on->arguments.size()<1,-1); - - const GDParser::IdentifierNode *in = (const GDParser::IdentifierNode *)on->arguments[0]; - - - Vector arguments; - int slevel = p_stack_level; - for(int i=1;iarguments.size();i++) { - - int ret = _parse_expression(codegen,on->arguments[i],slevel); - if (ret<0) - return ret; - if (ret&GDFunction::ADDR_TYPE_STACK<name)); //instance - codegen.opcodes.push_back(arguments.size()); //argument count - codegen.alloc_call(arguments.size()); - for(int i=0;iarguments[0]->type==GDParser::Node::TYPE_TYPE) { - //construct a basic type - ERR_FAIL_COND_V(on->arguments.size()<1,-1); - - const GDParser::TypeNode *tn = (const GDParser::TypeNode *)on->arguments[0]; - int vtype = tn->vtype; - - Vector arguments; - int slevel = p_stack_level; - for(int i=1;iarguments.size();i++) { - - int ret = _parse_expression(codegen,on->arguments[i],slevel); - if (ret<0) - return ret; - if (ret&GDFunction::ADDR_TYPE_STACK<arguments[0]->type==GDParser::Node::TYPE_BUILT_IN_FUNCTION) { - //built in function - - ERR_FAIL_COND_V(on->arguments.size()<1,-1); - - - Vector arguments; - int slevel = p_stack_level; - for(int i=1;iarguments.size();i++) { - - int ret = _parse_expression(codegen,on->arguments[i],slevel); - if (ret<0) - return ret; - - if (ret&GDFunction::ADDR_TYPE_STACK<(on->arguments[0])->function); - codegen.opcodes.push_back(on->arguments.size()-1); - codegen.alloc_call(on->arguments.size()-1); - for(int i=0;iarguments.size()<2,-1); - - const GDParser::Node *instance = on->arguments[0]; - - if (instance->type==GDParser::Node::TYPE_SELF) { - //room for optimization - - } - - - Vector arguments; - int slevel = p_stack_level; - - for(int i=0;iarguments.size();i++) { - - int ret; - - if (i==1) { - - if (on->arguments[i]->type!=GDParser::Node::TYPE_IDENTIFIER) { - _set_error("Attempt to call a non-identifier.",on); - return -1; - } - GDParser::IdentifierNode *id = static_cast(on->arguments[i]); - ret=codegen.get_name_map_pos(id->name); - - } else { - ret = _parse_expression(codegen,on->arguments[i],slevel); - if (ret<0) - return ret; - if (ret&GDFunction::ADDR_TYPE_STACK<arguments.size()-2); - codegen.alloc_call(on->arguments.size()-2); - for(int i=0;iarguments.size()!=2,-1); - - int slevel = p_stack_level; - bool named=(on->op==GDParser::OperatorNode::OP_INDEX_NAMED); - - int from = _parse_expression(codegen,on->arguments[0],slevel); - if (from<0) - return from; - - int index; - if (named) { - - index=codegen.get_name_map_pos(static_cast(on->arguments[1])->name); - - } else { - - if (on->arguments[1]->type==GDParser::Node::TYPE_CONSTANT && static_cast(on->arguments[1])->value.get_type()==Variant::STRING) { - //also, somehow, named (speed up anyway) - StringName name = static_cast(on->arguments[1])->value; - index=codegen.get_name_map_pos(name); - named=true; - - } else { - //regular indexing - if (from&GDFunction::ADDR_TYPE_STACK<arguments[1],slevel); - if (index<0) - return index; - } - } - - codegen.opcodes.push_back(named?GDFunction::OPCODE_GET_NAMED:GDFunction::OPCODE_GET); // perform operator - codegen.opcodes.push_back(from); // argument 1 - codegen.opcodes.push_back(index); // argument 2 (unary only takes one parameter) - - } break; - case GDParser::OperatorNode::OP_AND: { - - // AND operator with early out on failure - - int res = _parse_expression(codegen,on->arguments[0],p_stack_level); - if (res<0) - return res; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); - codegen.opcodes.push_back(res); - int jump_fail_pos=codegen.opcodes.size(); - codegen.opcodes.push_back(0); - - res = _parse_expression(codegen,on->arguments[1],p_stack_level); - if (res<0) - return res; - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); - codegen.opcodes.push_back(res); - int jump_fail_pos2=codegen.opcodes.size(); - codegen.opcodes.push_back(0); - - codegen.alloc_stack(p_stack_level); //it will be used.. - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN_TRUE); - codegen.opcodes.push_back(p_stack_level|GDFunction::ADDR_TYPE_STACK<arguments[0],p_stack_level); - if (res<0) - return res; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF); - codegen.opcodes.push_back(res); - int jump_success_pos=codegen.opcodes.size(); - codegen.opcodes.push_back(0); - - res = _parse_expression(codegen,on->arguments[1],p_stack_level); - if (res<0) - return res; - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF); - codegen.opcodes.push_back(res); - int jump_success_pos2=codegen.opcodes.size(); - codegen.opcodes.push_back(0); - - codegen.alloc_stack(p_stack_level); //it will be used.. - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN_FALSE); - codegen.opcodes.push_back(p_stack_level|GDFunction::ADDR_TYPE_STACK<arguments.size()!=2,-1); - - - if (on->arguments[0]->type==GDParser::Node::TYPE_OPERATOR && (static_cast(on->arguments[0])->op==GDParser::OperatorNode::OP_INDEX || static_cast(on->arguments[0])->op==GDParser::OperatorNode::OP_INDEX_NAMED)) { - //SET (chained) MODE!! - - int slevel=p_stack_level; - - GDParser::OperatorNode* op = static_cast(on->arguments[0]); - - /* Find chain of sets */ - - List chain; - - { - //create get/set chain - GDParser::OperatorNode* n=op; - while(true) { - - chain.push_back(n); - if (n->arguments[0]->type!=GDParser::Node::TYPE_OPERATOR) - break; - n = static_cast(n->arguments[0]); - if (n->op!=GDParser::OperatorNode::OP_INDEX && n->op!=GDParser::OperatorNode::OP_INDEX_NAMED) - break; - } - } - - /* Chain of gets */ - - //get at (potential) root stack pos, so it can be returned - int prev_pos = _parse_expression(codegen,chain.back()->get()->arguments[0],slevel); - if (prev_pos<0) - return prev_pos; - int retval=prev_pos; - - if (retval&GDFunction::ADDR_TYPE_STACK< setchain; - - for(List::Element *E=chain.back();E;E=E->prev()) { - - - if (E==chain.front()) //ignore first - break; - - bool named = E->get()->op==GDParser::OperatorNode::OP_INDEX_NAMED; - int key_idx; - - if (named) { - - key_idx = codegen.get_name_map_pos(static_cast(E->get()->arguments[1])->name); - } else { - - GDParser::Node *key = E->get()->arguments[1]; - key_idx = _parse_expression(codegen,key,slevel); - if (retval&GDFunction::ADDR_TYPE_STACK<(op)->op==GDParser::OperatorNode::OP_INDEX_NAMED) { - - - set_index=codegen.get_name_map_pos(static_cast(op->arguments[1])->name); - named=true; - } else { - - set_index = _parse_expression(codegen,op->arguments[1],slevel+1); - named=false; - } - - - if (set_index<0) - return set_index; - - if (set_index&GDFunction::ADDR_TYPE_STACK<arguments[0],slevel); - if (dst_address_a<0) - return -1; - - if (dst_address_a&GDFunction::ADDR_TYPE_STACK<arguments.size()!=2,false); - - - int slevel = p_stack_level; - - int src_address_a = _parse_expression(codegen,on->arguments[0],slevel); - if (src_address_a<0) - return -1; - - if (src_address_a&GDFunction::ADDR_TYPE_STACK<arguments[1],slevel); - if (src_address_b<0) - return -1; - - codegen.opcodes.push_back(GDFunction::OPCODE_EXTENDS_TEST); // perform operator - codegen.opcodes.push_back(src_address_a); // argument 1 - codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter) - - } break; - default: { - - - ERR_EXPLAIN("Bug in bytecode compiler, unexpected operator #"+itos(on->op)+" in parse tree while parsing expression."); - ERR_FAIL_V(0); //unreachable code - - } break; - } - - int dst_addr=(p_stack_level)|(GDFunction::ADDR_TYPE_STACK<line; - - for(int i=0;istatements.size();i++) { - - const GDParser::Node *s = p_block->statements[i]; - - - switch(s->type) { - case GDParser::Node::TYPE_NEWLINE: { - - const GDParser::NewLineNode *nl = static_cast(s); - codegen.opcodes.push_back(GDFunction::OPCODE_LINE); - codegen.opcodes.push_back(nl->line); - codegen.current_line=nl->line; - - } break; - case GDParser::Node::TYPE_CONTROL_FLOW: { - // try subblocks - - const GDParser::ControlFlowNode *cf = static_cast(s); - - switch(cf->cf_type) { - - - case GDParser::ControlFlowNode::CF_IF: { - -#ifdef DEBUG_ENABLED - codegen.opcodes.push_back(GDFunction::OPCODE_LINE); - codegen.opcodes.push_back(cf->line); - codegen.current_line=cf->line; -#endif - int ret = _parse_expression(codegen,cf->arguments[0],p_stack_level,false); - if (ret<0) - return ERR_PARSE_ERROR; - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); - codegen.opcodes.push_back(ret); - int else_addr=codegen.opcodes.size(); - codegen.opcodes.push_back(0); //temporary - - Error err = _parse_block(codegen,cf->body,p_stack_level,p_break_addr,p_continue_addr); - if (err) - return err; - - if (cf->body_else) { - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); - int end_addr=codegen.opcodes.size(); - codegen.opcodes.push_back(0); - codegen.opcodes[else_addr]=codegen.opcodes.size(); - - Error err = _parse_block(codegen,cf->body_else,p_stack_level,p_break_addr,p_continue_addr); - if (err) - return err; - - codegen.opcodes[end_addr]=codegen.opcodes.size(); - } else { - //end without else - codegen.opcodes[else_addr]=codegen.opcodes.size(); - - } - - } break; - case GDParser::ControlFlowNode::CF_FOR: { - - - - int slevel=p_stack_level; - int iter_stack_pos=slevel; - int iterator_pos = (slevel++)|(GDFunction::ADDR_TYPE_STACK<(cf->arguments[0])->name,iter_stack_pos); - - int ret = _parse_expression(codegen,cf->arguments[1],slevel,false); - if (ret<0) - return ERR_COMPILATION_FAILED; - - //assign container - codegen.opcodes.push_back(GDFunction::OPCODE_ASSIGN); - codegen.opcodes.push_back(container_pos); - codegen.opcodes.push_back(ret); - - //begin loop - codegen.opcodes.push_back(GDFunction::OPCODE_ITERATE_BEGIN); - codegen.opcodes.push_back(counter_pos); - codegen.opcodes.push_back(container_pos); - codegen.opcodes.push_back(codegen.opcodes.size()+4); - codegen.opcodes.push_back(iterator_pos); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); //skip code for next - codegen.opcodes.push_back(codegen.opcodes.size()+8); - //break loop - int break_pos=codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); //skip code for next - codegen.opcodes.push_back(0); //skip code for next - //next loop - int continue_pos=codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_ITERATE); - codegen.opcodes.push_back(counter_pos); - codegen.opcodes.push_back(container_pos); - codegen.opcodes.push_back(break_pos); - codegen.opcodes.push_back(iterator_pos); - - - Error err = _parse_block(codegen,cf->body,slevel,break_pos,continue_pos); - if (err) - return err; - - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); - codegen.opcodes.push_back(continue_pos); - codegen.opcodes[break_pos+1]=codegen.opcodes.size(); - - - codegen.pop_stack_identifiers(); - - } break; - case GDParser::ControlFlowNode::CF_WHILE: { - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); - codegen.opcodes.push_back(codegen.opcodes.size()+3); - int break_addr=codegen.opcodes.size(); - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); - codegen.opcodes.push_back(0); - int continue_addr=codegen.opcodes.size(); - - int ret = _parse_expression(codegen,cf->arguments[0],p_stack_level,false); - if (ret<0) - return ERR_PARSE_ERROR; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF_NOT); - codegen.opcodes.push_back(ret); - codegen.opcodes.push_back(break_addr); - Error err = _parse_block(codegen,cf->body,p_stack_level,break_addr,continue_addr); - if (err) - return err; - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); - codegen.opcodes.push_back(continue_addr); - - codegen.opcodes[break_addr+1]=codegen.opcodes.size(); - - } break; - case GDParser::ControlFlowNode::CF_SWITCH: { - - } break; - case GDParser::ControlFlowNode::CF_BREAK: { - - if (p_break_addr<0) { - - _set_error("'break'' not within loop",cf); - return ERR_COMPILATION_FAILED; - } - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); - codegen.opcodes.push_back(p_break_addr); - - } break; - case GDParser::ControlFlowNode::CF_CONTINUE: { - - if (p_continue_addr<0) { - - _set_error("'continue' not within loop",cf); - return ERR_COMPILATION_FAILED; - } - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); - codegen.opcodes.push_back(p_continue_addr); - - } break; - case GDParser::ControlFlowNode::CF_RETURN: { - - int ret; - - if (cf->arguments.size()) { - - ret = _parse_expression(codegen,cf->arguments[0],p_stack_level,false); - if (ret<0) - return ERR_PARSE_ERROR; - - } else { - - ret=GDFunction::ADDR_TYPE_NIL << GDFunction::ADDR_BITS; - } - - codegen.opcodes.push_back(GDFunction::OPCODE_RETURN); - codegen.opcodes.push_back(ret); - - } break; - - } - } break; - case GDParser::Node::TYPE_ASSERT: { - // try subblocks - - const GDParser::AssertNode *as = static_cast(s); - - int ret = _parse_expression(codegen,as->condition,p_stack_level,false); - if (ret<0) - return ERR_PARSE_ERROR; - - codegen.opcodes.push_back(GDFunction::OPCODE_ASSERT); - codegen.opcodes.push_back(ret); - } break; - case GDParser::Node::TYPE_LOCAL_VAR: { - - - const GDParser::LocalVarNode *lv = static_cast(s); - - codegen.add_stack_identifier(lv->name,p_stack_level++); - codegen.alloc_stack(p_stack_level); - new_identifiers++; - - } break; - default: { - //expression - int ret = _parse_expression(codegen,s,p_stack_level,true); - if (ret<0) - return ERR_PARSE_ERROR; - } break; - - } - - } - codegen.pop_stack_identifiers(); - return OK; -} - - -Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode *p_class,const GDParser::FunctionNode *p_func) { - - Vector bytecode; - CodeGen codegen; - - codegen.class_node=p_class; - codegen.script=p_script; - codegen.function_node=p_func; - codegen.stack_max=0; - codegen.current_line=0; - codegen.call_max=0; - codegen.debug_stack=ScriptDebugger::get_singleton()!=NULL; - - int stack_level=0; - - if (p_func) { - for(int i=0;iarguments.size();i++) { - int idx = i; - codegen.add_stack_identifier(p_func->arguments[i],i); - } - stack_level=p_func->arguments.size(); - } - - codegen.alloc_stack(stack_level); - - /* Parse initializer -if applies- */ - - bool is_initializer=false || !p_func; - - if (!p_func || String(p_func->name)=="_init") { - //parse initializer for class members - if (!p_func && p_class->extends_used && p_script->native.is_null()){ - - //call implicit parent constructor - codegen.opcodes.push_back(GDFunction::OPCODE_CALL_SELF_BASE); - codegen.opcodes.push_back(codegen.get_name_map_pos("_init")); - codegen.opcodes.push_back(0); - codegen.opcodes.push_back((GDFunction::ADDR_TYPE_STACK<initializer,stack_level); - if (err) - return err; - is_initializer=true; - - } - - /* Parse default argument code -if applies- */ - - Vector defarg_addr; - StringName func_name; - - if (p_func) { - if (p_func->default_values.size()) { - - codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_TO_DEF_ARGUMENT); - defarg_addr.push_back(codegen.opcodes.size()); - for(int i=0;idefault_values.size();i++) { - - _parse_expression(codegen,p_func->default_values[i],stack_level,true); - defarg_addr.push_back(codegen.opcodes.size()); - } - - - defarg_addr.invert(); - } - - - - Error err = _parse_block(codegen,p_func->body,stack_level); - if (err) - return err; - - func_name=p_func->name; - } else { - func_name="_init"; - } - - codegen.opcodes.push_back(GDFunction::OPCODE_END); - - GDFunction *gdfunc=NULL; - - //if (String(p_func->name)=="") { //initializer func - // gdfunc = &p_script->initializer; - - //} else { //regular func - p_script->member_functions[func_name]=GDFunction(); - gdfunc = &p_script->member_functions[func_name]; - //} - - if (p_func) - gdfunc->_static=p_func->_static; - - //constants - if (codegen.constant_map.size()) { - gdfunc->_constant_count=codegen.constant_map.size(); - gdfunc->constants.resize(codegen.constant_map.size()); - gdfunc->_constants_ptr=&gdfunc->constants[0]; - const Variant *K=NULL; - while((K=codegen.constant_map.next(K))) { - int idx = codegen.constant_map[*K]; - gdfunc->constants[idx]=*K; - } - } else { - - gdfunc->_constants_ptr=NULL; - gdfunc->_constant_count=0; - } - //global names - if (codegen.name_map.size()) { - - gdfunc->global_names.resize(codegen.name_map.size()); - gdfunc->_global_names_ptr = &gdfunc->global_names[0]; - for(Map::Element *E=codegen.name_map.front();E;E=E->next()) { - - gdfunc->global_names[E->get()]=E->key(); - } - gdfunc->_global_names_count=gdfunc->global_names.size(); - - } else { - gdfunc->_global_names_ptr = NULL; - gdfunc->_global_names_count =0; - } - - - if (codegen.opcodes.size()) { - - gdfunc->code=codegen.opcodes; - gdfunc->_code_ptr=&gdfunc->code[0]; - gdfunc->_code_size=codegen.opcodes.size(); - - } else { - - gdfunc->_code_ptr=NULL; - gdfunc->_code_size=0; - } - - if (defarg_addr.size()) { - - gdfunc->default_arguments=defarg_addr; - gdfunc->_default_arg_count=defarg_addr.size(); - gdfunc->_default_arg_ptr=&gdfunc->default_arguments[0]; - } else { - gdfunc->_default_arg_count=0; - gdfunc->_default_arg_ptr=NULL; - } - - gdfunc->_argument_count=p_func ? p_func->arguments.size() : 0; - gdfunc->_stack_size=codegen.stack_max; - gdfunc->_call_size=codegen.call_max; - gdfunc->name=func_name; - gdfunc->_script=p_script; - gdfunc->source=source; - if (p_func) { - gdfunc->_initial_line=p_func->line; - } else { - gdfunc->_initial_line=0; - } - - if (codegen.debug_stack) - gdfunc->stack_debug=codegen.stack_debug; - - if (is_initializer) - p_script->initializer=gdfunc; - - - return OK; -} - - - -Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDParser::ClassNode *p_class) { - - - p_script->native=Ref(); - p_script->base=Ref(); - p_script->_base=NULL; - p_script->members.clear(); - p_script->constants.clear(); - p_script->member_functions.clear(); - p_script->member_indices.clear(); - p_script->member_info.clear(); - p_script->initializer=NULL; - p_script->subclasses.clear(); - p_script->_owner=p_owner; - p_script->tool=p_class->tool; - p_script->name=p_class->name; - - - int index_from=0; - - if (p_class->extends_used) { - //do inheritance - String path = p_class->extends_file; - - Ref script; - Ref native; - - if (path!="") { - //path (and optionally subclasses) - - script = ResourceLoader::load(path); - if (script.is_null()) { - _set_error("Could not load base class: "+path,p_class); - return ERR_FILE_NOT_FOUND; - } - - if (p_class->extends_class.size()) { - - for(int i=0;iextends_class.size();i++) { - - String sub = p_class->extends_class[i]; - if (script->subclasses.has(sub)) { - - script=script->subclasses[sub]; - } else { - - _set_error("Could not find subclass: "+sub,p_class); - return ERR_FILE_NOT_FOUND; - } - } - } - - } else { - - ERR_FAIL_COND_V(p_class->extends_class.size()==0,ERR_BUG); - //look around for the subclasses - - String base=p_class->extends_class[0]; - GDScript *p = p_owner; - Ref base_class; - - while(p) { - - if (p->subclasses.has(base)) { - - base_class=p->subclasses[base]; - break; - } - p=p->_owner; - } - - if (base_class.is_valid()) { - - for(int i=1;iextends_class.size();i++) { - - String subclass=p_class->extends_class[i]; - - if (base_class->subclasses.has(subclass)) { - - base_class=base_class->subclasses[subclass]; - } else { - - _set_error("Could not find subclass: "+subclass,p_class); - return ERR_FILE_NOT_FOUND; - } - } - - script=base_class; - - - } else { - - if (p_class->extends_class.size()>1) { - - _set_error("Invalid inheritance (unknown class+subclasses)",p_class); - return ERR_FILE_NOT_FOUND; - - } - //if not found, try engine classes - if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) { - - _set_error("Unknown class: '"+base+"'",p_class); - return ERR_FILE_NOT_FOUND; - } - - int base_idx = GDScriptLanguage::get_singleton()->get_global_map()[base]; - native = GDScriptLanguage::get_singleton()->get_global_array()[base_idx]; - if (!native.is_valid()) { - - _set_error("Global not a class: '"+base+"'",p_class); - - return ERR_FILE_NOT_FOUND; - } - } - - - } - - if (script.is_valid()) { - - p_script->base=script; - p_script->_base=p_script->base.ptr(); - p_script->member_indices=script->member_indices; - - } else if (native.is_valid()) { - - p_script->native=native; - } else { - - _set_error("Could not determine inheritance",p_class); - return ERR_FILE_NOT_FOUND; - } - - - } - - - for(int i=0;ivariables.size();i++) { - - StringName name = p_class->variables[i].identifier; - if (p_script->member_indices.has(name)) { - _set_error("Member '"+name+"' already exists (in current or parent class)",p_class); - return ERR_ALREADY_EXISTS; - } - - if (p_class->variables[i]._export.type!=Variant::NIL) { - - p_script->member_info[name]=p_class->variables[i]._export; -#ifdef TOOLS_ENABLED - if (p_class->variables[i].default_value.get_type()!=Variant::NIL) { - - p_script->member_default_values[name]=p_class->variables[i].default_value; - } -#endif - } - - int new_idx = p_script->member_indices.size(); - p_script->member_indices[name]=new_idx; - p_script->members.insert(name); - - } - - for(int i=0;iconstant_expressions.size();i++) { - - StringName name = p_class->constant_expressions[i].identifier; - ERR_CONTINUE( p_class->constant_expressions[i].expression->type!=GDParser::Node::TYPE_CONSTANT ); - - GDParser::ConstantNode *constant = static_cast(p_class->constant_expressions[i].expression); - - p_script->constants.insert(name,constant->value); - //p_script->constants[constant->value].make_const(); - } - - - //parse sub-classes - - for(int i=0;isubclasses.size();i++) { - StringName name = p_class->subclasses[i]->name; - - Ref subclass = memnew( GDScript ); - - Error err = _parse_class(subclass.ptr(),p_script,p_class->subclasses[i]); - if (err) - return err; - p_script->subclasses.insert(name,subclass); - - } - - - //parse methods - - bool has_initializer=false; - for(int i=0;ifunctions.size();i++) { - - if (!has_initializer && p_class->functions[i]->name=="_init") - has_initializer=true; - Error err = _parse_function(p_script,p_class,p_class->functions[i]); - if (err) - return err; - } - - //parse static methods - - for(int i=0;istatic_functions.size();i++) { - - Error err = _parse_function(p_script,p_class,p_class->static_functions[i]); - if (err) - return err; - } - - - if (!has_initializer) { - //create a constructor - Error err = _parse_function(p_script,p_class,NULL); - if (err) - return err; - } - - return OK; -} - -Error GDCompiler::compile(const GDParser *p_parser,GDScript *p_script) { - - err_line=-1; - err_column=-1; - error=""; - parser=p_parser; - const GDParser::Node* root = parser->get_parse_tree(); - ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,ERR_INVALID_DATA); - - source=p_script->get_path(); - - - - Error err = _parse_class(p_script,NULL,static_cast(root)); - - if (err) - return err; - - return OK; - -} - -String GDCompiler::get_error() const { - - return error; -} -int GDCompiler::get_error_line() const{ - - return err_line; -} -int GDCompiler::get_error_column() const{ - - return err_column; -} - -GDCompiler::GDCompiler() -{ -} - - diff --git a/script/gdscript/gd_compiler.h b/script/gdscript/gd_compiler.h deleted file mode 100644 index cda221dab0..0000000000 --- a/script/gdscript/gd_compiler.h +++ /dev/null @@ -1,181 +0,0 @@ -/*************************************************************************/ -/* gd_compiler.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef GD_COMPILER_H -#define GD_COMPILER_H - -#include "gd_parser.h" -#include "gd_script.h" - - -class GDCompiler { - - const GDParser *parser; - struct CodeGen { - - - GDScript *script; - const GDParser::ClassNode *class_node; - const GDParser::FunctionNode *function_node; - - - bool debug_stack; - - - List< Map > stack_id_stack; - Map stack_identifiers; - - List stack_debug; - List< Map > block_identifier_stack; - Map block_identifiers; - - - void add_stack_identifier(const StringName& p_id,int p_stackpos) { - - stack_identifiers[p_id]=p_stackpos; - if (debug_stack) { - - block_identifiers[p_id]=p_stackpos; - GDFunction::StackDebug sd; - sd.added=true; - sd.line=current_line; - sd.identifier=p_id; - sd.pos=p_stackpos; - stack_debug.push_back(sd); - } - } - - void push_stack_identifiers() { - - stack_id_stack.push_back( stack_identifiers ); - if (debug_stack) { - - block_identifier_stack.push_back(block_identifiers); - block_identifiers.clear(); - } - } - - void pop_stack_identifiers() { - - stack_identifiers = stack_id_stack.back()->get(); - stack_id_stack.pop_back(); - - if (debug_stack) { - for (Map::Element *E=block_identifiers.front();E;E=E->next()) { - - GDFunction::StackDebug sd; - sd.added=false; - sd.identifier=E->key(); - sd.line=current_line; - sd.pos=E->get(); - stack_debug.push_back(sd); - } - block_identifiers=block_identifier_stack.back()->get(); - block_identifier_stack.pop_back(); - } - - } - - - // int get_identifier_pos(const StringName& p_dentifier) const; - HashMap constant_map; - Map name_map; - - int get_name_map_pos(const StringName& p_identifier) { - - int ret; - if (!name_map.has(p_identifier)) { - ret=name_map.size(); - name_map[p_identifier]=ret; - } else { - ret=name_map[p_identifier]; - } - return ret; - } - - - - int get_constant_pos(const Variant& p_constant) { - - - if (constant_map.has(p_constant)) - return constant_map[p_constant]; - int pos = constant_map.size(); - constant_map[p_constant]=pos; - return pos; - } - - Vector opcodes; - void alloc_stack(int p_level) { if (p_level >= stack_max) stack_max=p_level+1; } - void alloc_call(int p_params) { if (p_params >= call_max) call_max=p_params; } - - int current_line; - int stack_max; - int call_max; - }; - -#if 0 - void _create_index(const GDParser::OperatorNode *on); - void _create_call(const GDParser::OperatorNode *on); - - - int _parse_expression(const GDParser::Node *p_expr,CodeGen& codegen); - void _parse_block(GDParser::BlockNode *p_block); - void _parse_function(GDParser::FunctionNode *p_func); - Ref _parse_class(GDParser::ClassNode *p_class); -#endif - - void _set_error(const String& p_error,const GDParser::Node *p_node); - - bool _create_unary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level); - bool _create_binary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level); - - //int _parse_subexpression(CodeGen& codegen,const GDParser::BlockNode *p_block,const GDParser::Node *p_expression); - int _parse_assign_right_expression(CodeGen& codegen,const GDParser::OperatorNode *p_expression, int p_stack_level); - int _parse_expression(CodeGen& codegen,const GDParser::Node *p_expression, int p_stack_level,bool p_root=false); - Error _parse_block(CodeGen& codegen,const GDParser::BlockNode *p_block,int p_stack_level=0,int p_break_addr=-1,int p_continue_addr=-1); - Error _parse_function(GDScript *p_script,const GDParser::ClassNode *p_class,const GDParser::FunctionNode *p_func); - Error _parse_class(GDScript *p_script,GDScript *p_owner,const GDParser::ClassNode *p_class); - int err_line; - int err_column; - StringName source; - String error; - -public: - - Error compile(const GDParser *p_parser,GDScript *p_script); - - String get_error() const; - int get_error_line() const; - int get_error_column() const; - - GDCompiler(); -}; - - -#endif // COMPILER_H diff --git a/script/gdscript/gd_editor.cpp b/script/gdscript/gd_editor.cpp deleted file mode 100644 index c10cadf83f..0000000000 --- a/script/gdscript/gd_editor.cpp +++ /dev/null @@ -1,789 +0,0 @@ -/*************************************************************************/ -/* gd_editor.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "gd_script.h" -#include "gd_compiler.h" - - -void GDScriptLanguage::get_comment_delimiters(List *p_delimiters) const { - - p_delimiters->push_back("#"); - -} -void GDScriptLanguage::get_string_delimiters(List *p_delimiters) const { - - p_delimiters->push_back("\" \""); - p_delimiters->push_back("' '"); - - -} -String GDScriptLanguage::get_template(const String& p_class_name, const String& p_base_class_name) const { - - String _template = String()+ - "\nextends %BASE%\n\n"+ - "# member variables here, example:\n"+ - "# var a=2\n"+ - "# var b=\"textvar\"\n\n"+ - "func _ready():\n"+ - "\t# Initalization here\n"+ - "\tpass\n"+ - "\n"+ - "\n"; - - return _template.replace("%BASE%",p_base_class_name); -} - - - - -bool GDScriptLanguage::validate(const String& p_script, int &r_line_error,int &r_col_error,String& r_test_error, const String& p_path,List *r_functions) const { - - GDParser parser; - - Error err = parser.parse(p_script,p_path.get_base_dir()); - 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(root); - Map funcs; - for(int i=0;ifunctions.size();i++) { - - funcs[cl->functions[i]->line]=cl->functions[i]->name; - } - - for(int i=0;istatic_functions.size();i++) { - - funcs[cl->static_functions[i]->line]=cl->static_functions[i]->name; - } - - for (Map::Element *E=funcs.front();E;E=E->next()) { - - r_functions->push_back(E->get()+":"+itos(E->key())); - } - - - } - - return true; -} - -bool GDScriptLanguage::has_named_classes() const { - - return false; -} - -int GDScriptLanguage::find_function(const String& p_function,const String& p_code) const { - - GDTokenizer tokenizer; - tokenizer.set_code(p_code); - int indent=0; - while(tokenizer.get_token()!=GDTokenizer::TK_EOF && tokenizer.get_token()!=GDTokenizer::TK_ERROR) { - - if (tokenizer.get_token()==GDTokenizer::TK_NEWLINE) { - indent=tokenizer.get_token_line_indent(); - } - if (indent==0 && tokenizer.get_token()==GDTokenizer::TK_PR_FUNCTION && tokenizer.get_token(1)==GDTokenizer::TK_IDENTIFIER) { - - String identifier = tokenizer.get_token_identifier(1); - if (identifier==p_function) { - return tokenizer.get_token_line(); - } - } - tokenizer.advance(); - } - return -1; -} - -Script *GDScriptLanguage::create_script() const { - - return memnew( GDScript ); -} - -/* DEBUGGER FUNCTIONS */ - - -bool GDScriptLanguage::debug_break_parse(const String& p_file, int p_line,const String& p_error) { - //break because of parse error - - if (ScriptDebugger::get_singleton() && Thread::get_caller_ID()==Thread::get_main_ID()) { - - _debug_parse_err_line=p_line; - _debug_parse_err_file=p_file; - _debug_error=p_error; - ScriptDebugger::get_singleton()->debug(this,false); - return true; - } else { - return false; - } - -} - -bool GDScriptLanguage::debug_break(const String& p_error,bool p_allow_continue) { - - if (ScriptDebugger::get_singleton() && Thread::get_caller_ID()==Thread::get_main_ID()) { - - _debug_parse_err_line=-1; - _debug_parse_err_file=""; - _debug_error=p_error; - ScriptDebugger::get_singleton()->debug(this,p_allow_continue); - return true; - } else { - return false; - } - -} - -String GDScriptLanguage::debug_get_error() const { - - return _debug_error; -} - -int GDScriptLanguage::debug_get_stack_level_count() const { - - if (_debug_parse_err_line>=0) - return 1; - - - return _debug_call_stack_pos; -} -int GDScriptLanguage::debug_get_stack_level_line(int p_level) const { - - if (_debug_parse_err_line>=0) - return _debug_parse_err_line; - - ERR_FAIL_INDEX_V(p_level,_debug_call_stack_pos,-1); - - int l = _debug_call_stack_pos - p_level -1; - - return *(_call_stack[l].line); - -} -String GDScriptLanguage::debug_get_stack_level_function(int p_level) const { - - if (_debug_parse_err_line>=0) - return ""; - - ERR_FAIL_INDEX_V(p_level,_debug_call_stack_pos,""); - int l = _debug_call_stack_pos - p_level -1; - return _call_stack[l].function->get_name(); -} -String GDScriptLanguage::debug_get_stack_level_source(int p_level) const { - - if (_debug_parse_err_line>=0) - return _debug_parse_err_file; - - ERR_FAIL_INDEX_V(p_level,_debug_call_stack_pos,""); - int l = _debug_call_stack_pos - p_level -1; - return _call_stack[l].function->get_script()->get_path(); - -} -void GDScriptLanguage::debug_get_stack_level_locals(int p_level,List *p_locals, List *p_values, int p_max_subitems,int p_max_depth) { - - if (_debug_parse_err_line>=0) - return; - - ERR_FAIL_INDEX(p_level,_debug_call_stack_pos); - int l = _debug_call_stack_pos - p_level -1; - - GDFunction *f = _call_stack[l].function; - - List > locals; - - f->debug_get_stack_member_state(*_call_stack[l].line,&locals); - for( List >::Element *E = locals.front();E;E=E->next() ) { - - p_locals->push_back(E->get().first); - p_values->push_back(_call_stack[l].stack[E->get().second]); - } - -} -void GDScriptLanguage::debug_get_stack_level_members(int p_level,List *p_members, List *p_values, int p_max_subitems,int p_max_depth) { - - if (_debug_parse_err_line>=0) - return; - - ERR_FAIL_INDEX(p_level,_debug_call_stack_pos); - int l = _debug_call_stack_pos - p_level -1; - - - GDInstance *instance = _call_stack[l].instance; - - if (!instance) - return; - - Ref script = instance->get_script(); - ERR_FAIL_COND( script.is_null() ); - - - const Map& mi = script->debug_get_member_indices(); - - for(const Map::Element *E=mi.front();E;E=E->next()) { - - p_members->push_back(E->key()); - p_values->push_back( instance->debug_get_member_by_index(E->get())); - } - -} -void GDScriptLanguage::debug_get_globals(List *p_locals, List *p_values, int p_max_subitems,int p_max_depth) { - - //no globals are really reachable in gdscript -} -String GDScriptLanguage::debug_parse_stack_level_expression(int p_level,const String& p_expression,int p_max_subitems,int p_max_depth) { - - if (_debug_parse_err_line>=0) - return ""; - return ""; -} - -void GDScriptLanguage::get_recognized_extensions(List *p_extensions) const { - - p_extensions->push_back("gd"); -} - - -void GDScriptLanguage::get_public_functions(List *p_functions) const { - - - for(int i=0;ipush_back(GDFunctions::get_info(GDFunctions::Function(i))); - } -} - -void GDScriptLanguage::get_public_constants(List > *p_constants) const { - - Pair pi; - pi.first="PI"; - pi.second=Math_PI; - p_constants->push_back(pi); -} - -String GDScriptLanguage::make_function(const String& p_class,const String& p_name,const StringArray& p_args) const { - - String s="func "+p_name+"("; - if (p_args.size()) { - s+=" "; - for(int i=0;i0) - s+=", "; - s+=p_args[i]; - } - s+=" "; - } - s+="):\n\tpass # replace with function body\n"; - - return s; - -} - -static void _parse_native_symbols(const StringName& p_native,bool p_static,List* r_options) { - - if (!p_static) { - List methods; - ObjectTypeDB::get_method_list(p_native,&methods); - for(List::Element *E=methods.front();E;E=E->next()) { - if (!E->get().name.begins_with("_")) { - r_options->push_back(E->get().name); - } - } - } - - List constants; - ObjectTypeDB::get_integer_constant_list(p_native,&constants); - - for(List::Element *E=constants.front();E;E=E->next()) { - r_options->push_back(E->get()); - } - -} - - -static bool _parse_script_symbols(const Ref& p_script,bool p_static,List* r_options,List::Element *p_indices); - - -static bool _parse_completion_variant(const Variant& p_var,List* r_options,List::Element *p_indices) { - - if (p_indices) { - - bool ok; - Variant si = p_var.get(p_indices->get(),&ok); - if (!ok) - return false; - return _parse_completion_variant(si,r_options,p_indices->next()); - } else { - - switch(p_var.get_type()) { - - - case Variant::DICTIONARY: { - - Dictionary d=p_var; - List vl; - d.get_key_list(&vl); - for (List::Element *E=vl.front();E;E=E->next()) { - - if (E->get().get_type()==Variant::STRING) - r_options->push_back(E->get()); - } - - - List ml; - p_var.get_method_list(&ml); - for(List::Element *E=ml.front();E;E=E->next()) { - r_options->push_back(E->get().name); - } - - } break; - case Variant::OBJECT: { - - - Object *o=p_var; - if (o) { - print_line("OBJECT: "+o->get_type()); - if (p_var.is_ref() && o->cast_to()) { - - Ref gds = p_var; - _parse_script_symbols(gds,true,r_options,NULL); - } else if (o->is_type("GDNativeClass")){ - - GDNativeClass *gnc = o->cast_to(); - _parse_native_symbols(gnc->get_name(),false,r_options); - } else { - - print_line("REGULAR BLEND"); - _parse_native_symbols(o->get_type(),false,r_options); - } - } - - } break; - default: { - - List pi; - p_var.get_property_list(&pi); - for(List::Element *E=pi.front();E;E=E->next()) { - r_options->push_back(E->get().name); - } - List cl; - - p_var.get_numeric_constants_for_type(p_var.get_type(),&cl); - for(List::Element *E=cl.front();E;E=E->next()) { - r_options->push_back(E->get()); - } - - List ml; - p_var.get_method_list(&ml); - for(List::Element *E=ml.front();E;E=E->next()) { - r_options->push_back(E->get().name); - } - - } break; - } - - return true; - } - - -} - - -static void _parse_expression_node(const GDParser::Node *p_node,List* r_options,List::Element *p_indices) { - - - - if (p_node->type==GDParser::Node::TYPE_CONSTANT) { - - const GDParser::ConstantNode *cn=static_cast(p_node); - _parse_completion_variant(cn->value,r_options,p_indices?p_indices->next():NULL); - } else if (p_node->type==GDParser::Node::TYPE_DICTIONARY) { - - const GDParser::DictionaryNode *dn=static_cast(p_node); - for(int i=0;ielements.size();i++) { - - if (dn->elements[i].key->type==GDParser::Node::TYPE_CONSTANT) { - - const GDParser::ConstantNode *cn=static_cast(dn->elements[i].key); - if (cn->value.get_type()==Variant::STRING) { - - String str=cn->value; - if (p_indices) { - - if (str==p_indices->get()) { - _parse_expression_node(dn->elements[i].value,r_options,p_indices->next()); - return; - } - - } else { - r_options->push_back(str); - } - } - } - } - } -} - -static bool _parse_completion_block(const GDParser::BlockNode *p_block,int p_line,List* r_options,List::Element *p_indices) { - - for(int i=0;isub_blocks.size();i++) { - //parse inner first - if (p_line>=p_block->sub_blocks[i]->line && (p_line<=p_block->sub_blocks[i]->end_line || p_block->sub_blocks[i]->end_line==-1)) { - if (_parse_completion_block(p_block->sub_blocks[i],p_line,r_options,p_indices)) - return true; - } - } - - if (p_indices) { - - //parse indices in expressions :| - for (int i=0;istatements.size();i++) { - - if (p_block->statements[i]->line>p_line) - break; - - if (p_block->statements[i]->type==GDParser::BlockNode::TYPE_LOCAL_VAR) { - - const GDParser::LocalVarNode *lv=static_cast(p_block->statements[i]); - if (lv->assign && String(lv->name)==p_indices->get()) { - - _parse_expression_node(lv->assign,r_options,p_indices->next()); - return true; - } - } - } - - } else { - for(int i=0;ivariables.size();i++) { - //parse variables second - if (p_line>=p_block->variable_lines[i]) { - r_options->push_back(p_block->variables[i]); - } - else break; - - } - } - - return false; -} - - -static bool _parse_script_symbols(const Ref& p_script,bool p_static,List* r_options,List::Element *p_indices) { - - //for (Map >::Element ? - - if (!p_static && !p_indices) { - for(const Set::Element *E=p_script->get_members().front();E;E=E->next()) { - - r_options->push_back(E->get()); - } - } - - for (const Map::Element *E=p_script->get_constants().front();E;E=E->next()) { - - if( p_indices) { - if (p_indices->get()==String(E->get())) { - _parse_completion_variant(E->get(),r_options,p_indices->next()); - return true; - } - } else { - r_options->push_back(E->key()); - } - } - - if (!p_indices){ - for (const Map::Element *E=p_script->get_member_functions().front();E;E=E->next()) { - - if (E->get().is_static() || !p_static) - r_options->push_back(E->key()); - } - } - - if (p_script->get_base().is_valid()){ - if (_parse_script_symbols(p_script->get_base(),p_static,r_options,p_indices)) - return true; - } else if (p_script->get_native().is_valid() && !p_indices) { - _parse_native_symbols(p_script->get_native()->get_name(),p_static,r_options); - } - - return false; -} - - -static bool _parse_completion_class(const String& p_base_path,const GDParser::ClassNode *p_class,int p_line,List* r_options,List::Element *p_indices) { - - - static const char*_type_names[Variant::VARIANT_MAX]={ - "null","bool","int","float","String","Vector2","Rect2","Vector3","Matrix32","Plane","Quat","AABB","Matrix3","Trasnform", - "Color","Image","NodePath","RID","Object","InputEvent","Dictionary","Array","RawArray","IntArray","FloatArray","StringArray", - "Vector2Array","Vector3Array","ColorArray"}; - - if (p_indices && !p_indices->next()) { - for(int i=0;iget()==_type_names[i]) { - - List ic; - - Variant::get_numeric_constants_for_type(Variant::Type(i),&ic); - for(List::Element *E=ic.front();E;E=E->next()) { - r_options->push_back(E->get()); - } - return true; - } - } - } - - - - for(int i=0;isubclasses.size();i++) { - - if (p_line>=p_class->subclasses[i]->line && (p_line<=p_class->subclasses[i]->end_line || p_class->subclasses[i]->end_line==-1)) { - - if (_parse_completion_class(p_base_path,p_class->subclasses[i],p_line,r_options,p_indices)) - return true; - } - } - - bool in_static_func=false; - - for(int i=0;ifunctions.size();i++) { - - const GDParser::FunctionNode *fu = p_class->functions[i]; - - if (p_line>=fu->body->line && (p_line<=fu->body->end_line || fu->body->end_line==-1)) { - //if in function, first block stuff from outer to inner - if (_parse_completion_block(fu->body,p_line,r_options,p_indices)) - return true; - //then function arguments - if (!p_indices) { - for(int j=0;jarguments.size();j++) { - - r_options->push_back(fu->arguments[j]); - } - } - } - - } - - for(int i=0;istatic_functions.size();i++) { - - const GDParser::FunctionNode *fu = p_class->static_functions[i]; - - if (p_line>=fu->body->line && (p_line<=fu->body->end_line || fu->body->end_line==-1)) { - - //if in function, first block stuff from outer to inne - if (_parse_completion_block(fu->body,p_line,r_options,p_indices)) - return true; - //then function arguments - if (!p_indices) { - for(int j=0;jarguments.size();j++) { - - r_options->push_back(fu->arguments[j]); - } - } - - in_static_func=true; - } - - } - - - //add all local names - if (!p_indices) { - - if (!in_static_func) { - - for(int i=0;ivariables.size();i++) { - - r_options->push_back(p_class->variables[i].identifier); - } - } - - for(int i=0;iconstant_expressions.size();i++) { - - r_options->push_back(p_class->constant_expressions[i].identifier); - } - - if (!in_static_func) { - for(int i=0;ifunctions.size();i++) { - - r_options->push_back(p_class->functions[i]->name); - } - } - - for(int i=0;istatic_functions.size();i++) { - - r_options->push_back(p_class->static_functions[i]->name); - } - } - - - if (p_class->extends_used) { - //do inheritance - String path = p_class->extends_file; - - Ref script; - Ref native; - - if (path!="") { - //path (and optionally subclasses) - - script = ResourceLoader::load(path); - if (script.is_null()) { - return false; - } - - if (p_class->extends_class.size()) { - - for(int i=0;iextends_class.size();i++) { - - String sub = p_class->extends_class[i]; - if (script->get_subclasses().has(sub)) { - - script=script->get_subclasses()[sub]; - } else { - - return false; - } - } - } - - } else { - - ERR_FAIL_COND_V(p_class->extends_class.size()==0,false); - //look around for the subclasses - - String base=p_class->extends_class[0]; - Ref base_class; -#if 0 - while(p) { - - if (p->subclasses.has(base)) { - - base_class=p->subclasses[base]; - break; - } - p=p->_owner; - } - - if (base_class.is_valid()) { - - for(int i=1;iextends_class.size();i++) { - - String subclass=p_class->extends_class[i]; - - if (base_class->subclasses.has(subclass)) { - - base_class=base_class->subclasses[subclass]; - } else { - - _set_error("Could not find subclass: "+subclass,p_class); - return ERR_FILE_NOT_FOUND; - } - } - - - } else { -#endif - if (p_class->extends_class.size()>1) { - - return false; - - } - //if not found, try engine classes - if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) { - return false; - } - - int base_idx = GDScriptLanguage::get_singleton()->get_global_map()[base]; - native = GDScriptLanguage::get_singleton()->get_global_array()[base_idx]; - if (!native.is_valid()) { - return false; - } -#if 0 - } -#endif - - } - - if (script.is_valid()) { - if (_parse_script_symbols(script,in_static_func,r_options,p_indices)) - return true; - - } else if (native.is_valid() && !p_indices) { - - _parse_native_symbols(native->get_name(),in_static_func,r_options); - } - } - - return false; - -} - - -Error GDScriptLanguage::complete_keyword(const String& p_code, int p_line, const String& p_base_path, const String& p_base, List* r_options) { - - GDParser p; - Error err = p.parse(p_code,p_base_path); - // don't care much about error I guess - const GDParser::Node* root = p.get_parse_tree(); - ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,ERR_INVALID_DATA); - - const GDParser::ClassNode *cl = static_cast(root); - - List indices; - Vector spl = p_base.split("."); - - for(int i=0;i::Element *E=globals.front();E;E=E->next()) { - if (!indices.empty()) { - if (String(E->key())==indices.front()->get()) { - - _parse_completion_variant(global_array[E->get()],r_options,indices.front()->next()); - - return OK; - } - } else { - r_options->push_back(E->key()); - } - } - - return OK; -} - diff --git a/script/gdscript/gd_functions.cpp b/script/gdscript/gd_functions.cpp deleted file mode 100644 index 2930d9322c..0000000000 --- a/script/gdscript/gd_functions.cpp +++ /dev/null @@ -1,1218 +0,0 @@ -/*************************************************************************/ -/* gd_functions.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "gd_functions.h" -#include "math_funcs.h" -#include "object_type_db.h" -#include "reference.h" -#include "gd_script.h" -#include "os/os.h" - -const char *GDFunctions::get_func_name(Function p_func) { - - ERR_FAIL_INDEX_V(p_func,FUNC_MAX,""); - - static const char *_names[FUNC_MAX]={ - "sin", - "cos", - "tan", - "sinh", - "cosh", - "tanh", - "asin", - "acos", - "atan", - "atan2", - "sqrt", - "fmod", - "fposmod", - "floor", - "ceil", - "round", - "abs", - "sign", - "pow", - "log", - "exp", - "is_nan", - "is_inf", - "ease", - "decimals", - "stepify", - "lerp", - "dectime", - "randomize", - "randi", - "randf", - "rand_range", - "rand_seed", - "deg2rad", - "rad2deg", - "linear2db", - "db2linear", - "max", - "min", - "clamp", - "nearest_po2", - "weakref", - "convert", - "typeof", - "str", - "print", - "printt", - "printerr", - "printraw", - "range", - "load", - "inst2dict", - "dict2inst", - "print_stack", - }; - - return _names[p_func]; - -} - -void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Variant &r_ret,Variant::CallError &r_error) { - - r_error.error=Variant::CallError::CALL_OK; -#ifdef DEBUG_ENABLED - -#define VALIDATE_ARG_COUNT(m_count) \ - if (p_arg_countm_count) {\ - r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;\ - r_error.argument=m_count;\ - return;\ - } - -#define VALIDATE_ARG_NUM(m_arg) \ - if (!p_args[m_arg]->is_num()) {\ - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\ - r_error.argument=m_arg;\ - r_error.expected=Variant::REAL;\ - return;\ - } - -#else - -#define VALIDATE_ARG_COUNT(m_count) -#define VALIDATE_ARG_NUM(m_arg) -#endif - - //using a switch, so the compiler generates a jumptable - - switch(p_func) { - - case MATH_SIN: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::sin(*p_args[0]); - } break; - case MATH_COS: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::cos(*p_args[0]); - } break; - case MATH_TAN: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::tan(*p_args[0]); - } break; - case MATH_SINH: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::sinh(*p_args[0]); - } break; - case MATH_COSH: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::cosh(*p_args[0]); - } break; - case MATH_TANH: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::tanh(*p_args[0]); - } break; - case MATH_ASIN: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::asin(*p_args[0]); - } break; - case MATH_ACOS: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::acos(*p_args[0]); - } break; - case MATH_ATAN: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::atan(*p_args[0]); - } break; - case MATH_ATAN2: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - r_ret=Math::atan2(*p_args[0],*p_args[1]); - } break; - case MATH_SQRT: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::sqrt(*p_args[0]); - } break; - case MATH_FMOD: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - r_ret=Math::fmod(*p_args[0],*p_args[1]); - } break; - case MATH_FPOSMOD: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - r_ret=Math::fposmod(*p_args[0],*p_args[1]); - } break; - case MATH_FLOOR: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::floor(*p_args[0]); - } break; - case MATH_CEIL: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::ceil(*p_args[0]); - } break; - case MATH_ROUND: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::round(*p_args[0]); - } break; - case MATH_ABS: { - VALIDATE_ARG_COUNT(1); - if (p_args[0]->get_type()==Variant::INT) { - - int64_t i = *p_args[0]; - r_ret=ABS(i); - } else if (p_args[0]->get_type()==Variant::REAL) { - - real_t r = *p_args[0]; - r_ret=Math::abs(r); - } else { - - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::REAL; - } - } break; - case MATH_SIGN: { - VALIDATE_ARG_COUNT(1); - if (p_args[0]->get_type()==Variant::INT) { - - int64_t i = *p_args[0]; - r_ret= i < 0 ? -1 : ( i > 0 ? +1 : 0); - } else if (p_args[0]->get_type()==Variant::REAL) { - - real_t r = *p_args[0]; - r_ret= r < 0.0 ? -1.0 : ( r > 0.0 ? +1.0 : 0.0); - } else { - - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::REAL; - } - } break; - case MATH_POW: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - r_ret=Math::pow(*p_args[0],*p_args[1]); - } break; - case MATH_LOG: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::log(*p_args[0]); - } break; - case MATH_EXP: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::exp(*p_args[0]); - } break; - case MATH_ISNAN: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::is_nan(*p_args[0]); - } break; - case MATH_ISINF: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::is_inf(*p_args[0]); - } break; - case MATH_EASE: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - r_ret=Math::ease(*p_args[0],*p_args[1]); - } break; - case MATH_DECIMALS: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::decimals(*p_args[0]); - } break; - case MATH_STEPIFY: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - r_ret=Math::stepify(*p_args[0],*p_args[1]); - } break; - case MATH_LERP: { - VALIDATE_ARG_COUNT(3); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - r_ret=Math::lerp(*p_args[0],*p_args[1],*p_args[2]); - } break; - case MATH_DECTIME: { - VALIDATE_ARG_COUNT(3); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - r_ret=Math::dectime(*p_args[0],*p_args[1],*p_args[2]); - } break; - case MATH_RANDOMIZE: { - Math::randomize(); - r_ret=Variant(); - } break; - case MATH_RAND: { - r_ret=Math::rand(); - } break; - case MATH_RANDF: { - r_ret=Math::randf(); - } break; - case MATH_RANDOM: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - r_ret=Math::random(*p_args[0],*p_args[1]); - } break; - case MATH_RANDSEED: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - uint32_t seed=*p_args[0]; - int ret = Math::rand_from_seed(&seed); - Array reta; - reta.push_back(ret); - reta.push_back(seed); - r_ret=reta; - - } break; - case MATH_DEG2RAD: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::deg2rad(*p_args[0]); - } break; - case MATH_RAD2DEG: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::rad2deg(*p_args[0]); - } break; - case MATH_LINEAR2DB: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::linear2db(*p_args[0]); - } break; - case MATH_DB2LINEAR: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret=Math::db2linear(*p_args[0]); - } break; - case LOGIC_MAX: { - VALIDATE_ARG_COUNT(2); - if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT) { - - int64_t a = *p_args[0]; - int64_t b = *p_args[1]; - r_ret=MAX(a,b); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - - real_t a = *p_args[0]; - real_t b = *p_args[1]; - - r_ret=MAX(a,b); - } - - } break; - case LOGIC_MIN: { - VALIDATE_ARG_COUNT(2); - if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT) { - - int64_t a = *p_args[0]; - int64_t b = *p_args[1]; - r_ret=MIN(a,b); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - - real_t a = *p_args[0]; - real_t b = *p_args[1]; - - r_ret=MIN(a,b); - } - } break; - case LOGIC_CLAMP: { - VALIDATE_ARG_COUNT(3); - if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT && p_args[2]->get_type()==Variant::INT) { - - int64_t a = *p_args[0]; - int64_t b = *p_args[1]; - int64_t c = *p_args[2]; - r_ret=CLAMP(a,b,c); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - - real_t a = *p_args[0]; - real_t b = *p_args[1]; - real_t c = *p_args[2]; - - r_ret=CLAMP(a,b,c); - } - } break; - case LOGIC_NEAREST_PO2: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - int64_t num = *p_args[0]; - r_ret = nearest_power_of_2(num); - } break; - case OBJ_WEAKREF: { - VALIDATE_ARG_COUNT(1); - if (p_args[0]->get_type()!=Variant::OBJECT) { - - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::OBJECT; - return; - - } - - if (p_args[0]->is_ref()) { - - REF r = *p_args[0]; - if (!r.is_valid()) { - r_ret=Variant(); - return; - } - - Ref wref = memnew( WeakRef ); - wref->set_ref(r); - r_ret=wref; - } else { - Object *obj = *p_args[0]; - if (!obj) { - r_ret=Variant(); - return; - } - Ref wref = memnew( WeakRef ); - wref->set_obj(obj); - r_ret=wref; - } - - - - - } break; - case TYPE_CONVERT: { - VALIDATE_ARG_COUNT(2); - VALIDATE_ARG_NUM(1); - int type=*p_args[1]; - if (type<0 || type>=Variant::VARIANT_MAX) { - - ERR_PRINT("Invalid type argument to convert()"); - r_ret=Variant::NIL; - - } else { - - - r_ret=Variant::construct(Variant::Type(type),p_args,1,r_error); - } - } break; - case TYPE_OF: { - - VALIDATE_ARG_COUNT(1); - r_ret = p_args[0]->get_type(); - - } break; - case TEXT_STR: { - - String str; - for(int i=0;ioperator String();; - if (i==0) - str=os; - else - str+=os; - } - - r_ret=str; - - } break; - case TEXT_PRINT: { - - String str; - for(int i=0;ioperator String(); - } - - //str+="\n"; - print_line(str); - r_ret=Variant(); - - - } break; - case TEXT_PRINT_TABBED: { - - String str; - for(int i=0;ioperator String(); - } - - //str+="\n"; - print_line(str); - r_ret=Variant(); - - - } break; - - case TEXT_PRINTERR: { - - String str; - for(int i=0;ioperator String(); - } - - //str+="\n"; - OS::get_singleton()->printerr("%s\n",str.utf8().get_data()); - r_ret=Variant(); - - } break; - case TEXT_PRINTRAW: { - String str; - for(int i=0;ioperator String(); - } - - //str+="\n"; - OS::get_singleton()->print("%s\n",str.utf8().get_data()); - r_ret=Variant(); - - } break; - case GEN_RANGE: { - - - - switch(p_arg_count) { - - case 0: { - - r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument=1; - - } break; - case 1: { - - VALIDATE_ARG_NUM(0); - int count=*p_args[0]; - Array arr(true); - if (count<=0) { - r_ret=arr; - return; - } - Error err = arr.resize(count); - if (err!=OK) { - r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; - r_ret=Variant(); - return; - } - - for(int i=0;i=to) { - r_ret=arr; - return; - } - Error err = arr.resize(to-from); - if (err!=OK) { - r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; - r_ret=Variant(); - return; - } - for(int i=from;i=to && incr>0) { - r_ret=arr; - return; - } - if (from<=to && incr<0) { - r_ret=arr; - return; - } - - //calculate how many - int count=0; - if (incr>0) { - - count=((to-from-1)/incr)+1; - } else { - - count=((from-to-1)/-incr)+1; - } - - - Error err = arr.resize(count); - - if (err!=OK) { - r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; - r_ret=Variant(); - return; - } - - if (incr>0) { - int idx=0; - for(int i=from;ito;i+=incr) { - arr[idx++]=i; - } - } - - r_ret=arr; - } break; - default: { - - r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; - r_error.argument=3; - } break; - } - - } break; - case RESOURCE_LOAD: { - VALIDATE_ARG_COUNT(1); - if (p_args[0]->get_type()!=Variant::STRING) { - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_ret=Variant(); - } - r_ret=ResourceLoader::load(*p_args[0]); - - } - case INST2DICT: { - - VALIDATE_ARG_COUNT(1); - - if (p_args[0]->get_type()==Variant::NIL) { - r_ret=Variant(); - } else if (p_args[0]->get_type()!=Variant::OBJECT) { - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_ret=Variant(); - } else { - - Object *obj = *p_args[0]; - if (!obj) { - r_ret=Variant(); - - } else if (!obj->get_script_instance() || obj->get_script_instance()->get_language()!=GDScriptLanguage::get_singleton()) { - - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::DICTIONARY; - ERR_PRINT("Not a script with an instance"); - - } else { - - GDInstance *ins = static_cast(obj->get_script_instance()); - Ref base = ins->get_script(); - if (base.is_null()) { - - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::DICTIONARY; - ERR_PRINT("Not based on a script"); - return; - - } - - - GDScript *p = base.ptr(); - Vector sname; - - while(p->_owner) { - - sname.push_back(p->name); - p=p->_owner; - } - sname.invert(); - - - if (!p->path.is_resource_file()) { - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::DICTIONARY; - print_line("PATH: "+p->path); - ERR_PRINT("Not based on a resource file"); - - return; - } - - NodePath cp(sname,Vector(),false); - - Dictionary d(true); - d["@subpath"]=cp; - d["@path"]=p->path; - - - p = base.ptr(); - - while(p) { - - for(Set::Element *E=p->members.front();E;E=E->next()) { - - Variant value; - if (ins->get(E->get(),value)) { - - String k = E->get(); - if (!d.has(k)) { - d[k]=value; - } - } - } - - p=p->_base; - } - - r_ret=d; - - } - } - - } break; - case DICT2INST: { - - VALIDATE_ARG_COUNT(1); - - if (p_args[0]->get_type()!=Variant::DICTIONARY) { - - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::DICTIONARY; - return; - } - - Dictionary d = *p_args[0]; - - if (!d.has("@path")) { - - r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument=0; - r_error.expected=Variant::OBJECT; - return; - } - - Ref