diff --git a/hbrt/ops_compare.go b/hbrt/ops_compare.go index 8982c83..4d0c274 100644 --- a/hbrt/ops_compare.go +++ b/hbrt/ops_compare.go @@ -209,22 +209,38 @@ func (t *Thread) Not() { // And pops two values, pushes logical AND. // Harbour evaluates both sides (no short-circuit in VM ops). func (t *Thread) And() { - b := t.pop() - a := t.pop() - if !a.IsLogical() || !b.IsLogical() { - panic(t.argError(".AND.", a, b)) + t.sp -= 2 + a := t.stack[t.sp] + b := t.stack[t.sp+1] + t.stack[t.sp+1] = cachedNil + if a.Type() == tLogical && b.Type() == tLogical { + if a.scalar != 0 && b.scalar != 0 { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ + return } - t.push(MakeBool(a.AsBool() && b.AsBool())) + panic(t.argError(".AND.", a, b)) } // Or pops two values, pushes logical OR. func (t *Thread) Or() { - b := t.pop() - a := t.pop() - if !a.IsLogical() || !b.IsLogical() { - panic(t.argError(".OR.", a, b)) + t.sp -= 2 + a := t.stack[t.sp] + b := t.stack[t.sp+1] + t.stack[t.sp+1] = cachedNil + if a.Type() == tLogical && b.Type() == tLogical { + if a.scalar != 0 || b.scalar != 0 { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ + return } - t.push(MakeBool(a.AsBool() || b.AsBool())) + panic(t.argError(".OR.", a, b)) } // InString implements the $ operator: "bc" $ "abcde" → .T.