Author Topic: ((or temp1025 temp1024) nsLeft:)?  (Read 9332 times)

0 Members and 1 Guest are viewing this topic.

Offline doomlazer

((or temp1025 temp1024) nsLeft:)?
« on: January 03, 2024, 09:44:25 PM »
In the LSL5 SCI-Scripts decompile Interface.sc line 250 is:
Code: [Select]
((or temp1025 temp1024) nsLeft:)

SCiCompanion will not compile the code, but:

Code: [Select]
(= temp0 0)
(= temp1 5)
(Printf {%d} (or temp0 temp1))

Results in 1, not 5. The following would work:

Code: [Select]
((if temp1025 else temp1024) nsLeft:)
But does 'or' ever?



Offline Kawa

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #1 on: January 04, 2024, 05:12:48 AM »
That's not what or does. It doesn't return one value or the other, it returns true if one or the other given value is truthy. Or rather, if any of the given values is truthy, since you can have any amount of values to check if they're non-zero.

For comparison, and is true if all its arguments are truthy.

You must be talking about this line in the OG LSL5 source: ((or subI mainI) nsLeft?). Considering you must have a main text and may end up with a multi-language subtitle,  mainI will always be a valid non-zero pointer and subI may be. (or subI mainI) will return the pointer to either DText object, and that control's nsLeft is then queried to pass on to editI. If there was a subtitle, it'll use the subtitle's nsLeft. If there wasn't, the pointer will be zero, false-y, and the guaranteed main text is used instead. The same trick is then used to move editI below the text (plus a bit) regardless of subI's existence.

... wait, hold up. That explanation doesn't track with observation. *checks the relevant original Sierra docs*.
Quote
(or e1 e2 [e3...])
Evaluates to TRUE if any of the expressions are non-zero, else FALSE.

I must've misunderstood what Print does there.



Edit: came back to do some more in-person testing. The manual is right.
Code: [Select]
;; Sanity checks.
(= theOne 42)
(= theOther 420)
(Printf "theOne = %d\ntheOther = %d" theOne theOther)
(Printf "one OR the other = %d" (or theOne theOther))
;; ^- should be TRUE
(= theOne 0)
(= theOther 420)
(Printf "theOne = %d\ntheOther = %d" theOne theOther)
(Printf "one OR the other = %d" (or theOne theOther))
;; ^- should be TRUE
(= theOne 42)
(= theOther 0)
(Printf "theOne = %d\ntheOther = %d" theOne theOther)
(Printf "one OR the other = %d" (or theOne theOther))
;; ^- should be TRUE
(= theOne 0)
(= theOther 0)
(Printf "theOne = %d\ntheOther = %d" theOne theOther)
(Printf "one OR the other = %d" (or theOne theOther))
;; ^- should be FALSE

(= theOne (DCIcon new:))
(theOne nsLeft: 100)
(= theOther 0)
(Printf "theOne = %d\ntheOther = %d" theOne theOther)
(Printf "one OR the other = %d" (or theOne theOther))
;; ^- should be TRUE
;; v-- Does not compile, "nsLeft is not a property or method on type 'bool'."
;;; (Printf "one OR the other's nsLeft = %d" ((or theOne theOther) nsLeft?))
(Printf "IF one ELSE the other's nsLeft = %d" ((if theOne else theOther) nsLeft?))
;; ^- should be 100
;; v-- Also does not compile, same reason. This is adapted straight from SCI10's Interface.
;;; (theOne
;;; moveTo:
;;; ((or theOne theOther) nsLeft?)
;;; ((or theOne theOther) nsBottom?)
;;; )
(theOne
moveTo:
((if theOne else theOther) nsLeft?)
((if theOne else theOther) nsBottom?)
)

; This tracks with the documentation: OR returns TRUE or FALSE, not the first valid pointer.

I would say that maybe Sierra's compiler handled things Differently?, but both the '88 and '94 manuals agree that what SCI 1.0 does here should not work.
« Last Edit: January 04, 2024, 06:35:02 AM by Kawa »

Offline OmerMor

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #2 on: January 04, 2024, 12:07:51 PM »
Here's the snippet from the original source code:
Code: [Select]
; if editI we add it right under text item
(if editI
(editI
moveTo:
((or subI mainI) nsLeft?)
(+ MARGIN ((or subI mainI) nsBottom?))
)
; add edit item and resize the dialog
(theDialog add:editI, setSize:)
)
https://github.com/historicalsource/leisure-suit-larry-5/blob/341bc91b5529c3243220a7fe77cc6b041c8022d4/SYSTEM/INTRFACE.SC#L1568C2-L1577C3

Offline Kawa

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #3 on: January 04, 2024, 12:22:17 PM »
Note that, again, this original code won't compile in SCI Companion and has no business doing so in accordance with the original Sierra documentation.

(actually there's a bunch of things about the OG source that won't work in SCI Companion but that's not exactly on the level of "weird or behavior"...)
« Last Edit: January 04, 2024, 12:27:40 PM by Kawa »

Offline lskovlun

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #4 on: January 04, 2024, 01:08:12 PM »
Note that, again, this original code won't compile in SCI Companion and has no business doing so in accordance with the original Sierra documentation.
Parts of the original documentation are outdated/inconsistent with reality. See, for example, the documentation of kernel calls that don't exist in any published SCI version. The changelogs are funny in places as well.

Offline Kawa

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #5 on: January 04, 2024, 01:19:49 PM »
Even the 1994 SCI32 version?

Mind you, the observed behavior of or matches what you'd expect from most any other language. What it does in here Print makes no sense to begin with.

Offline doomlazer

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #6 on: January 04, 2024, 04:17:50 PM »
So maybe the interpreter knows to return the value instead of the bool when used with something that doesn't accept a bool? Weird.

Offline Kawa

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #7 on: January 04, 2024, 04:43:46 PM »
It's not the interpreter's doing. I checked. After all, though there are and and or VM opcodes, those are for the binary math operations & and |.

Code: [Select]
(procedure (OrIsIt &tmp theOne theOther)
(= theOne 42)
(= theOther 420)
(Printf "theOne = %d\ntheOther = %d" theOne theOther)
(Printf "one OR the other = %d" (or theOne theOther))
)
Code: [Select]
; Manually cleaned up.
(procedure oneOrTheOther
link 2

; (= theOne 42)
ldi 42
sat theOne

; (= theOther 420)
ldi 420
sat theOther

; (Printf "theOne = %d\ntheOther = %d" theOne theOther)
pushi 3 ;argc
lofss "theOne = %d\ntheOther = %d"
lst theOne
lst theOther
calle 399 Printf 6

; (Printf "one OR the other = %d" (or theOne theOther))
push2
lofss "one OR the other = %d"

; THIS IS WHERE THE FUN BEGINS
lat theOne ; this MAY be zero/false.
bt itWasTrue
lat theOther
bnt orElse

itWasTrue:
ldi 1 ; True! So we replace theOne (42) with true (1).

orElse:
push ; push whatever's in the acc as the second arg, but hold up...

calle 399 Printf 4
ret
)
You might notice there's no ldi 0 for the "other" case. But if I change the values to 0 and 420, I still get a 1/true result. But then, understanding ASM is not my strongest suit. Perhaps someone smarter can tell me how this works out.

But if I use (if theOne else theOther):
Code: [Select]
; (Printf "IF one ELSE the other = %d" (if theOne else theOther))
push2
lofss "IF one ELSE the other = %d"

; THIS IS WHERE THE FUN BEGINS... AGAIN!
lat theOne
bnt itWasNotTrue ; note: BNT, not BT.
jmp finally

itWasNotTrue:
lat theOther

finally:
push ; push one or the other, as seen in the acc, as the second arg

calle 399 Printf 4
In this case, it loads the one (42 here) into the accumulator, then if said acc happens to be false-y, it loads the other (420) instead.

Offline doomlazer

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #8 on: January 05, 2024, 05:22:58 PM »
Here is what Sluicebox had to say on the matter:

Quote from: Sluicebox via email
Sierra's compiler generates bt (branch if true) instructions for 'or'.

Code: [Select]
(or temp0 temp1)

lat 00    ; acc = temp0
bt  label ; branch to label if acc != 0
lat 01    ; acc = temp1
label:

This is the behavior that the Interface script depends on, and that's what Sierra's compiler always did. But that's not what your Printf test did, because Companion did something different:

Code: [Select]
lat 00     ; acc = temp0
bt  label1 ; branch to label1 if acc != 0
lat 01     ; acc = temp1
bnt label2 ; branch to label2 if acc == 0
label1:
ldi 01     ; acc = 1
label2:

also:

Quote from: Sluicebox via email
...I just peeked at Compiler.cpp:

Code: [Select]
if (Operator == BinaryOperator::LogicalAnd || Operator == BinaryOperator::LogicalOr)
{
    // Handle && and || when not used in a condition.
    // Basically, we write an "if statement" that evaluates to 1 or 0
    return _WriteFakeIfStatement(context, *this);
}

So the answer is simply that SCICompanion is handling Or differently than Sierra's compiler. Not really a problem because SC decompiles the LSL5 Interface.sc code in question as an If statement. Also, the Sierra source code can be converted by hand before compiling to achieve the same functionality.

Offline Kawa

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #9 on: January 05, 2024, 05:36:15 PM »
So... should SCI Companion be adjusted to mimic SC, which does not match its own official documentation nor any other language, or should we just let it be and use (if A else B) where other sources say (or A B)?

And if so, who's gonna do that? Cos I wouldn't know where to begin replacing that part Sluicebox found.

Offline doomlazer

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #10 on: January 05, 2024, 05:43:46 PM »
I had a brief look at the SCICompanion repo and it's certainly beyond my abilities to fix.

Offline Kawa

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #11 on: January 05, 2024, 05:52:35 PM »
I mean I could figure it out maybe but my brain is the fried.

Offline doomlazer

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #12 on: January 05, 2024, 05:58:35 PM »
The closer SCICompanion matches SC the better IMO.

Offline Kawa

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #13 on: January 05, 2024, 07:29:01 PM »
I don't like it, but I guess I'll put it on the list.

Offline doomlazer

Re: ((or temp1025 temp1024) nsLeft:)?
« Reply #14 on: January 05, 2024, 08:25:25 PM »
Feel free to ignore it completely. The code just stood out as odd when I saw it. SCICompanion already includes a workaround and my curiosity has been satiated.


SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.053 seconds with 22 queries.