aboutsummaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/gd_compiler.cpp82
-rw-r--r--modules/gdscript/gd_editor.cpp64
-rw-r--r--modules/gdscript/gd_parser.cpp23
-rw-r--r--modules/gdscript/gd_parser.h2
-rw-r--r--modules/gdscript/gd_script.cpp23
-rw-r--r--modules/gdscript/gd_script.h8
6 files changed, 164 insertions, 38 deletions
diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp
index 90c83c201..f1b7ad009 100644
--- a/modules/gdscript/gd_compiler.cpp
+++ b/modules/gdscript/gd_compiler.cpp
@@ -185,51 +185,59 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
//TRY CLASS CONSTANTS
- GDScript *scr = codegen.script;
- GDNativeClass *nc=NULL;
- while(scr) {
+ GDScript *owner = codegen.script;
+ while (owner) {
- if (scr->constants.has(identifier)) {
+ GDScript *scr = owner;
+ GDNativeClass *nc=NULL;
+ while(scr) {
- //int idx=scr->constants[identifier];
- int idx = codegen.get_name_map_pos(identifier);
- return idx|(GDFunction::ADDR_TYPE_CLASS_CONSTANT<<GDFunction::ADDR_BITS); //argument (stack root)
+ if (scr->constants.has(identifier)) {
+
+ //int idx=scr->constants[identifier];
+ int idx = codegen.get_name_map_pos(identifier);
+ return idx|(GDFunction::ADDR_TYPE_CLASS_CONSTANT<<GDFunction::ADDR_BITS); //argument (stack root)
+ }
+ if (scr->native.is_valid())
+ nc=scr->native.ptr();
+ scr=scr->_base;
}
- if (scr->native.is_valid())
- nc=scr->native.ptr();
- scr=scr->_base;
- }
- // CLASS C++ Integer Constant
+ // CLASS C++ Integer Constant
- if (nc) {
+ if (nc) {
- bool success=false;
- int constant = ObjectTypeDB::get_integer_constant(nc->get_name(),identifier,&success);
- if (success) {
- Variant key=constant;
- int idx;
+ 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)) {
+ if (!codegen.constant_map.has(key)) {
- idx=codegen.constant_map.size();
- codegen.constant_map[key]=idx;
+ idx=codegen.constant_map.size();
+ codegen.constant_map[key]=idx;
- } else {
- idx=codegen.constant_map[key];
+ } else {
+ idx=codegen.constant_map[key];
+ }
+
+ return idx|(GDFunction::ADDR_TYPE_LOCAL_CONSTANT<<GDFunction::ADDR_BITS); //make it a local constant (faster access)
}
- return idx|(GDFunction::ADDR_TYPE_LOCAL_CONSTANT<<GDFunction::ADDR_BITS); //make it a local constant (faster access)
}
+ owner=owner->_owner;
}
- if (codegen.script->subclasses.has(identifier)) {
+ /*
+ handled in constants now
+ if (codegen.script->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<<GDFunction::ADDR_BITS); //make it a local constant (faster access)
- }
+ }*/
if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
@@ -1255,6 +1263,16 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode *
gdfunc->name=func_name;
gdfunc->_script=p_script;
gdfunc->source=source;
+
+#ifdef DEBUG_ENABLED
+
+ {
+ gdfunc->func_cname=(String(source)+" - "+String(func_name)).utf8();
+ gdfunc->_func_cname=gdfunc->func_cname.get_data();
+
+ }
+
+#endif
if (p_func) {
gdfunc->_initial_line=p_func->line;
} else {
@@ -1303,6 +1321,16 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
if (path!="") {
//path (and optionally subclasses)
+ if (path.is_rel_path()) {
+
+ String base = p_script->get_path();
+ if (base=="" || base.is_rel_path()) {
+ _set_error("Could not resolve relative path for parent class: "+path,p_class);
+ return ERR_FILE_NOT_FOUND;
+ }
+ path=base.get_base_dir().plus_file(path);
+ }
+
script = ResourceLoader::load(path);
if (script.is_null()) {
_set_error("Could not load base class: "+path,p_class);
@@ -1457,6 +1485,8 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
Error err = _parse_class(subclass.ptr(),p_script,p_class->subclasses[i]);
if (err)
return err;
+
+ p_script->constants.insert(name,subclass); //once parsed, goes to the list of constants
p_script->subclasses.insert(name,subclass);
}
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index f8717c292..5f5de8b5d 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -787,3 +787,67 @@ Error GDScriptLanguage::complete_keyword(const String& p_code, int p_line, const
return OK;
}
+void GDScriptLanguage::auto_indent_code(String& p_code,int p_from_line,int p_to_line) const {
+
+
+ Vector<String> lines = p_code.split("\n");
+ List<int> indent_stack;
+
+ for(int i=0;i<lines.size();i++) {
+
+ String l = lines[i];
+ int tc=0;
+ for(int j=0;j<l.length();j++) {
+ if (l[j]==' ' || l[j]=='\t') {
+
+ tc++;
+ } else {
+ break;
+ }
+ }
+
+
+ String st = l.substr(tc,l.length()).strip_edges();
+ if (st=="" || st.begins_with("#"))
+ continue; //ignore!
+
+ int ilevel=0;
+ if (indent_stack.size()) {
+ ilevel=indent_stack.back()->get();
+ }
+
+ if (tc>ilevel) {
+ indent_stack.push_back(tc);
+ } else if (tc<ilevel) {
+ while(indent_stack.size() && indent_stack.back()->get()>tc) {
+ indent_stack.pop_back();
+ }
+
+ if (indent_stack.size() && indent_stack.back()->get()!=tc)
+ indent_stack.push_back(tc); //this is not right but gets the job done
+ }
+
+ if (i>=p_from_line) {
+
+ l="";
+ for(int j=0;j<indent_stack.size();j++)
+ l+="\t";
+ l+=st;
+
+
+ } else if (i>p_to_line) {
+ break;
+ }
+
+ //print_line(itos(indent_stack.size())+","+itos(tc)+": "+l);
+ lines[i]=l;
+ }
+
+ p_code="";
+ for(int i=0;i<lines.size();i++) {
+ if (i>0)
+ p_code+="\n";
+ p_code+=lines[i];
+ }
+
+}
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index f540660cd..2829132d9 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -1221,6 +1221,15 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
return; //go back a level
}
+ if (pending_newline!=-1) {
+
+ NewLineNode *nl = alloc_node<NewLineNode>();
+ nl->line=pending_newline;
+ p_block->statements.push_back(nl);
+ pending_newline=-1;
+
+ }
+
switch(token) {
@@ -1234,16 +1243,19 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
} break;
case GDTokenizer::TK_NEWLINE: {
- NewLineNode *nl = alloc_node<NewLineNode>();
- nl->line=tokenizer->get_token_line();
- p_block->statements.push_back(nl);
-
if (!_parse_newline()) {
if (!error_set) {
p_block->end_line=tokenizer->get_token_line();
+ pending_newline=p_block->end_line;
+
}
return;
}
+
+ NewLineNode *nl = alloc_node<NewLineNode>();
+ nl->line=tokenizer->get_token_line();
+ p_block->statements.push_back(nl);
+
} break;
case GDTokenizer::TK_CF_PASS: {
if (tokenizer->get_token(1)!=GDTokenizer::TK_SEMICOLON && tokenizer->get_token(1)!=GDTokenizer::TK_NEWLINE ) {
@@ -1782,6 +1794,7 @@ void GDParser::_parse_class(ClassNode *p_class) {
case GDTokenizer::TK_PR_FUNCTION: {
bool _static=false;
+ pending_newline=-1;
if (tokenizer->get_token(-1)==GDTokenizer::TK_PR_STATIC) {
@@ -2490,6 +2503,7 @@ void GDParser::clear() {
tab_level.push_back(0);
error_line=0;
error_column=0;
+ pending_newline=-1;
parenthesis=0;
current_export.type=Variant::NIL;
error="";
@@ -2501,6 +2515,7 @@ GDParser::GDParser() {
head=NULL;
list=NULL;
tokenizer=NULL;
+ pending_newline=-1;
clear();
}
diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h
index 278e5f543..825bd954d 100644
--- a/modules/gdscript/gd_parser.h
+++ b/modules/gdscript/gd_parser.h
@@ -362,6 +362,8 @@ private:
int error_line;
int error_column;
+ int pending_newline;
+
List<int> tab_level;
String base_path;
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 299a7d3e5..d18378286 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -76,16 +76,21 @@ Variant *GDFunction::_get_variant(int p_address,GDInstance *p_instance,GDScript
case ADDR_TYPE_CLASS_CONSTANT: {
//todo change to index!
- GDScript *s=p_script;
+ GDScript *o=p_script;
ERR_FAIL_INDEX_V(address,_global_names_count,NULL);
const StringName *sn = &_global_names_ptr[address];
- while(s) {
- Map<StringName,Variant>::Element *E=s->constants.find(*sn);
- if (E) {
- return &E->get();
+ while(o) {
+ GDScript *s=o;
+ while(s) {
+
+ Map<StringName,Variant>::Element *E=s->constants.find(*sn);
+ if (E) {
+ return &E->get();
+ }
+ s=s->_base;
}
- s=s->_base;
+ o=o->_owner;
}
@@ -384,6 +389,8 @@ Variant GDFunction::call(GDInstance *p_instance,const Variant **p_args, int p_ar
}
}
+
+
} else {
GDNativeClass *nc= obj_B->cast_to<GDNativeClass>();
@@ -1154,6 +1161,9 @@ GDFunction::GDFunction() {
_stack_size=0;
_call_size=0;
name="<anonymous>";
+#ifdef DEBUG_ENABLED
+ _func_cname=NULL;
+#endif
}
@@ -2148,6 +2158,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"and",
"or",
"export",
+ "assert",
0};
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 983899240..56da0bb2e 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -118,10 +118,13 @@ friend class GDCompiler;
Vector<Variant> constants;
Vector<StringName> global_names;
Vector<int> default_arguments;
-
Vector<int> code;
+#ifdef DEBUG_ENABLED
+ CharString func_cname;
+ const char*_func_cname;
+#endif
- List<StackDebug> stack_debug;
+ List<StackDebug> stack_debug;
_FORCE_INLINE_ Variant *_get_variant(int p_address,GDInstance *p_instance,GDScript *p_script,Variant &self,Variant *p_stack,String& r_error) const;
_FORCE_INLINE_ String _get_call_error(const Variant::CallError& p_err, const String& p_where,const Variant**argptrs) const;
@@ -427,6 +430,7 @@ public:
virtual int find_function(const String& p_function,const String& p_code) const;
virtual String make_function(const String& p_class,const String& p_name,const StringArray& p_args) const;
virtual Error complete_keyword(const String& p_code, int p_line, const String& p_base_path,const String& p_keyword, List<String>* r_options);
+ virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const;
/* DEBUGGER FUNCTIONS */