🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Namespaces can not be resolved well in some cases

Started by
14 comments, last by y18a 5 years, 10 months ago

Thanks for the continuous bug reports. This really helps a lot.

I'll investigate this latest problem too.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement

I've fixed this problem in revision 2525. 

Observe, within namespace X the symbol A represents the class X::A, not the global variable A, so it is correct the script fails to compile. It was just not correct that it gave an assert failure.

(in previous version of AngelScript it managed to identify the global variable A, but that was unintentional and due to the inconsistent symbol lookups used in different scenarios in the compiler.)

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Thanks for fixing it. 

All existing code now works.

 

Quote

so it is correct the script fails to compile

It is the same as the following. I was exhausted because I was heavily using it.


float3 v;
l = v.length;
l = v.length();

 

By the way, With this revision, I applied the following hack patch again.


enum TestEnum { A, B };

auto e = TestEnum(A|B);  // e = TestEnum(TestEnum::A|TestEnum::B)

I want to make `ep.requireEnumScope` true, but since it becomes redundant, I'm hacking as above.

 

Specifically, I am doing the following hacks.
However, there are codes that do not pass well with this.
Is there any hint?


+        if( ns && engine->ep.requireEnumScope && errNode )
+        {
+          asCString parentName(&script->code[errNode->parent->tokenPos], errNode->parent->tokenLength);
+          asDWORD value = 0;
+          asCDataType dt;
+          if( builder->GetEnumValue( parentName.AddressOf(), dt, value, outFunc->objectType ? outFunc->objectType->nameSpace : outFunc->nameSpace) )
+          {
+            outResult->type.SetConstantDW(dt, value);
+            outResult->symbolNamespace = ns;
+            return SL_ENUMVAL;
+          }
+        }

         // Is it an enum value?
         if (ns && !engine->ep.requireEnumScope)
         {

 

Quote

It is the same as the following. I was exhausted because I was heavily using it.



float3 v;
l = v.length;
l = v.length();

Yes. The compiler no longer allows this ambiguity on the symbol resolution. I understand it could break some existing scripts, but hopefully the gain of a more consistent language outweighs this.

Quote

Specifically, I am doing the following hacks.
However, there are codes that do not pass well with this.
Is there any hint?

I would be better positioned to help if you told me in which scenario your hack doesn't work.

Your hack would possibly be more functional if instead of just looking at the parentNode for the name, you would instead recursively move up the parent nodes until you find the node with nodeType = snFunctionCall or snConstructCall. Then only with that you would do a symbol lookup of that name in that node to see if it matches the name of an enum type. Use the SymbolLookup method itself to do the lookup, so you get the benefit of the namespace searches etc too.

But, in your case, you seem to be a bit inconsistent yourself. Why do you want to use asEP_REQUIRE_ENUM_SCOPE to enforce the use of the enum type, but then in some case not enforce it? Why not just leave asEP_REQUIRE_ENUM_SCOPE disabled?

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Quote

so you get the benefit of the namespace searches etc too.

Indeed, my dirty hacks seem to have not been doing well in other namespaces.
I will try to investigate by referring to what you taught me.

 

Quote

But, in your case, you seem to be a bit inconsistent yourself...

Normally, It is clearly stated as follows.


func(XXX::Left);
func(YYY::Right);

I only want to use this abbreviated dirty hack when I do an operation to convert it to an integer with a bit operator and cast it to an enumeration type.

 

Actually, I wanted to explicitly state what I omit as follows.


enum XXX { Left=1,Center=2,Right=4 };
enum YYY { Left=1,Center=2,Right=4 };

func( XXX(.Left|.Right) ); 
func( YYY(.Left|.Right) ); 
func( XXX::Left ); // I do this when not performing bit operation.

In this case it is impossible to write dangerous code. ( ex, int Left; etc... )
but, I do not understand enough to do it.
So, I compromised.

This topic is closed to new replies.

Advertisement