Explorar o código

Now const/enums have local scope. Also checking for double global declarations on the same compilation unit.

mingodad %!s(int64=13) %!d(string=hai) anos
pai
achega
f4b7786eab
Modificáronse 4 ficheiros con 66 adicións e 23 borrados
  1. 25 0
      samples/test-local-constants.nut
  2. 41 12
      squirrel/sqcompiler.cpp
  3. 0 10
      squirrel/sqfuncstate.cpp
  4. 0 1
      squirrel/sqfuncstate.h

+ 25 - 0
samples/test-local-constants.nut

@@ -0,0 +1,25 @@
+function localF(){
+	const fryday = 5;
+	enum E {a, b};
+	print(fryday, E.a, E.b);
+	//fryday = 6;
+	//print(fryday);
+}
+//print(fryday);
+localF();
+enum E {a=1.2, b=2.5};
+print(E.b);
+
+/*
+//local 
+enum Enum {dad, red, blue};
+
+const car = 3;
+
+local function localFunc(){
+	const mar = 999;
+	print(mar, Enum.blue);
+} 
+
+localFunc();
+*/

+ 41 - 12
squirrel/sqcompiler.cpp

@@ -35,7 +35,8 @@ struct SQScope {
 #define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \
 #define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \
 					 ++_scope.nested; \
 					 ++_scope.nested; \
 					 _scope.outers = _fs->_outers; \
 					 _scope.outers = _fs->_outers; \
-					 _scope.stacksize = _fs->GetStackSize();
+					 _scope.stacksize = _fs->GetStackSize();\
+					 _scope_consts.push_back(SQTable::Create(_ss(_vm),0));
 
 
 #define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \
 #define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \
 							if(_fs->CountOuters(_scope.stacksize)) { \
 							if(_fs->CountOuters(_scope.stacksize)) { \
@@ -46,7 +47,8 @@ struct SQScope {
 #define END_SCOPE_NO_CLOSE() {	if(_fs->GetStackSize() != _scope.stacksize) { \
 #define END_SCOPE_NO_CLOSE() {	if(_fs->GetStackSize() != _scope.stacksize) { \
 							_fs->SetStackSize(_scope.stacksize); \
 							_fs->SetStackSize(_scope.stacksize); \
 						} \
 						} \
-						_scope = __oldscope__; \
+						_scope = __oldscope__; \
+						_scope_consts.pop_back();\
 					}
 					}
 
 
 #define END_SCOPE() {	SQInteger oldouters = _fs->_outers;\
 #define END_SCOPE() {	SQInteger oldouters = _fs->_outers;\
@@ -81,8 +83,8 @@ public:
 		_scope.outers = 0;
 		_scope.outers = 0;
 		_scope.stacksize = 0;
 		_scope.stacksize = 0;
 		_scope.nested = 0;
 		_scope.nested = 0;
-		compilererror = NULL;
-	}
+		compilererror = NULL;
+	}
 	static void ThrowError(void *ud, const SQChar *s) {
 	static void ThrowError(void *ud, const SQChar *s) {
 		SQCompiler *c = (SQCompiler *)ud;
 		SQCompiler *c = (SQCompiler *)ud;
 		c->Error(s);
 		c->Error(s);
@@ -103,6 +105,34 @@ public:
 		va_start(vl, s);
 		va_start(vl, s);
 		scvfprintf(stderr, s, vl);
 		scvfprintf(stderr, s, vl);
 		va_end(vl);
 		va_end(vl);
+	}
+	bool IsConstant(const SQObject &name,SQObject &e){
+        SQObjectPtr val;
+	    for(int i=_scope.nested-1; i >= 0; --i){
+	        if(_table(_scope_consts[i])->Get(name,val)) {
+	            e = val;
+	            return true;
+	        }
+	    }
+        if(_table(_ss(_vm)->_consts)->Get(name,val)) {
+            e = val;
+            return true;
+        }
+        return false;
+	}
+	bool ConstsExists(const SQObjectPtr &key){
+        if(_scope.nested && _table(_scope_consts[_scope.nested-1])->Exists(key)) return true;
+        return _table(_ss(_vm)->_consts)->Exists(key);
+	}
+	bool ConstsGet(const SQObjectPtr &key,SQObjectPtr &val){
+	    for(int i=_scope.nested-1; i >= 0; --i){
+	        if(_table(_scope_consts[i])->Get(key,val)) return true;
+	    }
+	    return _table(_ss(_vm)->_consts)->Get(key,val);
+	}
+	bool ConstsNewSlot(const SQObjectPtr &key, const SQObjectPtr &val){
+	    if(_scope.nested) return _table(_scope_consts[_scope.nested-1])->NewSlot(key,val);
+	    return _table(_ss(_vm)->_consts)->NewSlot(key,val);
 	}
 	}
 	void Lex(){	_token = _lex.Lex();}
 	void Lex(){	_token = _lex.Lex();}
 	SQObjectPtr GetTokenObject(SQInteger tok)
 	SQObjectPtr GetTokenObject(SQInteger tok)
@@ -335,15 +365,14 @@ public:
 			Lex();
 			Lex();
 			SQObject id = Expect(TK_IDENTIFIER);
 			SQObject id = Expect(TK_IDENTIFIER);
 			Expect('=');
 			Expect('=');
-			SQTable *enums = _table(_ss(_vm)->_consts);
 			SQObjectPtr strongid = id;
 			SQObjectPtr strongid = id;
-			if(enums->Exists(strongid)) {
+			if(ConstsExists(strongid)) {
 			    strongid.Null();
 			    strongid.Null();
 			    Error(_SC("constant '%s' already exists"), _stringval(id));
 			    Error(_SC("constant '%s' already exists"), _stringval(id));
 			}
 			}
 			SQObject val = ExpectScalar();
 			SQObject val = ExpectScalar();
 			OptionalSemicolon();
 			OptionalSemicolon();
-			enums->NewSlot(strongid,SQObjectPtr(val));
+			ConstsNewSlot(strongid,SQObjectPtr(val));
 			strongid.Null();
 			strongid.Null();
 
 
 			}
 			}
@@ -802,7 +831,7 @@ public:
 					}
 					}
 				}
 				}
 
 
-				else if(_fs->IsConstant(id, constant)) {
+				else if(IsConstant(id, constant)) {
 					/* Handle named constant */
 					/* Handle named constant */
 					SQObjectPtr constval;
 					SQObjectPtr constval;
 					SQObject    constid;
 					SQObject    constid;
@@ -1483,9 +1512,8 @@ if(color == "yellow"){
 		Expect(_SC('{'));
 		Expect(_SC('{'));
 
 
         //checkLocalNameScope(id, _scope.nested);
         //checkLocalNameScope(id, _scope.nested);
-		SQTable *enums = _table(_ss(_vm)->_consts);
 		SQObjectPtr strongid = id;
 		SQObjectPtr strongid = id;
-		if(enums->Exists(strongid)) {
+		if(ConstsExists(strongid)) {
 		    strongid.Null();
 		    strongid.Null();
 		    Error(_SC("constant '%s' already exists"), _stringval(id));
 		    Error(_SC("constant '%s' already exists"), _stringval(id));
 		}
 		}
@@ -1511,7 +1539,7 @@ if(color == "yellow"){
 			if(_token == ',') Lex();
 			if(_token == ',') Lex();
 		}
 		}
 
 
-		enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
+		ConstsNewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
 		strongid.Null();
 		strongid.Null();
 		Lex();
 		Lex();
 	}
 	}
@@ -1715,7 +1743,8 @@ private:
 	SQScope _scope;
 	SQScope _scope;
 	SQChar *compilererror;
 	SQChar *compilererror;
 	jmp_buf _errorjmp;
 	jmp_buf _errorjmp;
-	SQVM *_vm;
+	SQVM *_vm;
+	SQObjectPtrVec _scope_consts;
 };
 };
 
 
 bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
 bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)

+ 0 - 10
squirrel/sqfuncstate.cpp

@@ -275,16 +275,6 @@ void SQFuncState::SetStackSize(SQInteger n)
 	}
 	}
 }
 }
 
 
-bool SQFuncState::IsConstant(const SQObject &name,SQObject &e)
-{
-	SQObjectPtr val;
-	if(_table(_sharedstate->_consts)->Get(name,val)) {
-		e = val;
-		return true;
-	}
-	return false;
-}
-
 bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
 bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
 {
 {
 	if(stkpos>=_vlocals.size())return false;
 	if(stkpos>=_vlocals.size())return false;

+ 0 - 1
squirrel/sqfuncstate.h

@@ -49,7 +49,6 @@ struct SQFuncState
 	bool IsLocal(SQUnsignedInteger stkpos);
 	bool IsLocal(SQUnsignedInteger stkpos);
 	SQObject CreateString(const SQChar *s,SQInteger len = -1);
 	SQObject CreateString(const SQChar *s,SQInteger len = -1);
 	SQObject CreateTable();
 	SQObject CreateTable();
-	bool IsConstant(const SQObject &name,SQObject &e);
 	SQInteger _returnexp;
 	SQInteger _returnexp;
 	SQLocalVarInfoVec _vlocals;
 	SQLocalVarInfoVec _vlocals;
 	SQIntVec _targetstack;
 	SQIntVec _targetstack;