Comments (8)
I am not in a position at the moment to edit the code. My usual laptop with all the development stuff is in for repairs right now, but I very strongly suspect the culprit is this, if someone else wants to implement the fix:
The error happens with UNTIL but not with IF because of the fact that UNTIL makes use of the opcode LogicalNot, while IF doesn't. The actual error is inside OpcodeLogicalNot. In the case where the operand is a number rather than a boolean, OpcodeLogicalNot is failing to invert the boolean meaning of the value.
In the file "Compilation/Opcode.cs", OpcodeLogicNot.execute() has these lines:
if (value is bool)
result = !((bool)value);
else if (value is int)
result = -((int)value);
else if (value is double)
result = -((double)value);
If the input was 1 (or any other nonzero number), then the output should be 0. But the code above would make it a -1, which is still true.
Similarly, if the input is 0, the output should be 1 (or any other nonzero number). But the above code would leave it at 0. (negative zero), making no change.
This is my suggested replacement for that code section. Only the two lines marked with the comment "// changed line" are different:
if (value is bool)
result = !((bool)value);
else if (value is int)
result = ((int) ( (value==0) ? 1: 0 ) ); // changed line.
else if (value is double)
result = ((double) ( (value==0.0) ? 1.0 : 0.0 ) ); // changed line.
from kos.
That won't work because (regardless of the name) the opcode OpcodeLogicNot is also responsible for negating numbers, so it's used in expressions like "-(2*3)".
There are two ways to solve this:
- Add a new opcode to branch if the expression is true (therefore not needing to use OpcodeLogicNot)
- In the compiler code for the UNTIL statement add an opcode OpcodeLogicToBool before the OpcodeLogicNot.
I'll look into this once I'm back from work.
from kos.
Ahh, that explain Issue #29 then. The meaning of arithmetic negation and the meaning of logical not have been conflated together at a very deep level of the RISC instruction set.
I would much prefer the following third way to solve it, as it solves other problems too and makes the design cleaner and more correct:
SO this third way to fix it is to stop trying to overload boolean nots with arithmetic negation. They are two entirely different operations.
It's better to allow a script writer to write:
set x to not x.
versus
set x to -x.
to make it clear which was meant. Use the minus sign for its intended purpose of arithmetic negation, and not for boolean inversion. (And then if you try to use the minus sign for booleans after this update, it's an error. I doubt this will break anyone's code because nobody' is going to have been in the habit of using the minus sign for boolean nots. It's not a thing a person would guess to try.)
I definitely do not like keeping the name "OpcodeLogicNot" when that's not what the opcode actually does. It's misleadingly named. If it's a dual-purpose opcode then it should be called something that reflects that. (or, even better, have two different opcodes, one for negation and one for not.)
In fact, I feel so passionately about this that I'm willing to put in the work to implement this as two different opcodes myself if you'll wait a bit for my computer to be repaired (probably by tomorrow morning).
RISC is a nice principle, but in this case it looks like it was taken to the extreme to the point where it caused distinct mathematical operations to be conflated in a buggy way.
from kos.
I suppose another way to fix it if you don't want to define any new opcodes is to insert a call to OpcodeLogicToBool not just here, but everywhere a logical operation occurs. I'd say that if you do that, though, that the name of OpcodeLogicNot should be changed to reflect the fact that that's not really what it does if it also does double-duty as an arithmetic negater.
from kos.
They have to be to separate opcodes, the current implementation is just something temporal I threw together during development and forgot about it.
from kos.
Okay I'm actually very glad you said that, because a different opcode for logical not versus arithmetic negation would be my preferred solution too. It's much cleaner.
I just got my computer back from the shop so I should be able to look into this tonight.
from kos.
Now addressed with pull request #46 instead of #38.
from kos.
Closing as this was fixed in pull request #46.
from kos.
Related Issues (20)
- Scope seems to be considered differently 'on board' and 'in Archive' HOT 4
- Resizing terminal repeatedly causes a memory leak [BUG]
- Feature Request: "On Script Error" setting on controller part
- Setting part module field value has no effect for some mods
- docs:"make latexpdf" generates only 19 pages (and they are almost empty) HOT 1
- Some system monospace fonts are not recognized by kOS terminal HOT 2
- Redundancy in compiled form of UNTIL
- Changing the active vessel using `kuniverse` from IVA mode will break the internal camera until the next scene change HOT 4
- KOSVesselModule can populate allInstances dictionary with an ID of 0
- KOSVesselModules has a memory leak problem
- Terminal breaks when something is typed that extends beyond the terminal window
- ship:control:mainthrottle doesn't work unless some other raw control is set [BUG]
- Global vars 'undefined' in local scope after running any program. HOT 6
- Undefined var when checking if the same var is defined HOT 2
- make sure kosnametag doesn't spend time updating
- Get create-release up and running
- Get docs building on github actions
- CI: changelog updating
- Function gets called when checking if a var with same name is defined HOT 2
- Equality comparisons for ELEMENTS and :CREW are broken HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kos.