@@ -520,11 +520,11 @@ static InterpretResult run(VM* vm) {
520520 concatenate (vm );
521521 } else {
522522 // Enhanced Error Logging
523- Value v1 = peek (vm , 0 );
524- Value v2 = peek (vm , 1 );
523+ Value v1 = peek (vm , 1 ); // a
524+ Value v2 = peek (vm , 0 ); // b
525525 runtimeError (vm , "Operands must be two numbers or two strings. Got types %d and %d" ,
526- IS_OBJ (v1 ) ? OBJ_TYPE (v1 ) : -1 ,
527- IS_OBJ (v2 ) ? OBJ_TYPE (v2 ) : -1 );
526+ IS_OBJ (v1 ) ? OBJ_TYPE (v1 ) : ( IS_NUMBER ( v1 ) ? -2 : -1 ) ,
527+ IS_OBJ (v2 ) ? OBJ_TYPE (v2 ) : ( IS_NUMBER ( v2 ) ? -2 : -1 ) );
528528 return INTERPRET_RUNTIME_ERROR ;
529529 }
530530 DISPATCH ();
@@ -1007,7 +1007,13 @@ static InterpretResult run(VM* vm) {
10071007 case OP_EQUAL : {
10081008 Value b = pop (vm );
10091009 Value a = pop (vm );
1010- push (vm , BOOL_VAL (a == b ));
1010+ if (IS_STRING (a ) && IS_STRING (b )) {
1011+ ObjString * s1 = AS_STRING (a );
1012+ ObjString * s2 = AS_STRING (b );
1013+ push (vm , BOOL_VAL (s1 == s2 || (s1 -> length == s2 -> length && memcmp (s1 -> chars , s2 -> chars , s1 -> length ) == 0 )));
1014+ } else {
1015+ push (vm , BOOL_VAL (a == b ));
1016+ }
10111017 break ;
10121018 }
10131019 case OP_GREATER : {
@@ -1046,7 +1052,11 @@ static InterpretResult run(VM* vm) {
10461052 push (vm , strVal );
10471053 concatenate (vm );
10481054 } else {
1049- runtimeError (vm , "Operands must be two numbers or two strings." );
1055+ Value v1 = peek (vm , 1 ); // a
1056+ Value v2 = peek (vm , 0 ); // b
1057+ runtimeError (vm , "Operands must be two numbers or two strings. Got types %d and %d" ,
1058+ IS_OBJ (v1 ) ? OBJ_TYPE (v1 ) : (IS_NUMBER (v1 ) ? -2 : -1 ),
1059+ IS_OBJ (v2 ) ? OBJ_TYPE (v2 ) : (IS_NUMBER (v2 ) ? -2 : -1 ));
10501060 return INTERPRET_RUNTIME_ERROR ;
10511061 }
10521062 break ;
0 commit comments